@shaferllc/keel 0.83.4 → 0.83.6
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/AGENTS.md +5 -4
- package/README.md +23 -15
- package/dist/accounts/provider.js +12 -2
- package/dist/billing/provider.js +12 -2
- package/dist/mcp/cloud.d.ts +2 -1
- package/dist/mcp/cloud.js +117 -8
- package/dist/mcp/server.js +4 -2
- package/dist/teams/provider.js +12 -2
- package/docs/ai-manifest.json +8 -1
- package/docs/ai.md +22 -11
- package/docs/changelog.md +21 -0
- package/docs/from-install-to-deploy.md +186 -0
- package/docs/getting-started.md +19 -27
- package/docs/starter-kits.md +2 -1
- package/llms-full.txt +344 -147
- package/llms.txt +1 -0
- package/package.json +1 -1
package/llms-full.txt
CHANGED
|
@@ -7,6 +7,199 @@ https://github.com/shaferllc/keel/blob/main/docs. Generated by `npm run build:ai
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- source: docs/from-install-to-deploy.md -->
|
|
13
|
+
|
|
14
|
+
# From install to deploy
|
|
15
|
+
|
|
16
|
+
One path from zero to a live Keel app — locally, on Cloudflare yourself, or on
|
|
17
|
+
**Keel Cloud** with an AI agent. Pick the track that matches how you want to
|
|
18
|
+
ship; everything else is optional.
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
create-keeljs → npm run dev → (optional MCP) → deploy
|
|
22
|
+
↘
|
|
23
|
+
Keel Cloud (optional)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Requirements
|
|
27
|
+
|
|
28
|
+
- Node.js **≥ 22**
|
|
29
|
+
- npm
|
|
30
|
+
- For self-hosted edge deploys: a [Cloudflare](https://dash.cloudflare.com) account
|
|
31
|
+
and [Wrangler](https://developers.cloudflare.com/workers/wrangler/) (ships with
|
|
32
|
+
the kits as a devDependency)
|
|
33
|
+
- For Keel Cloud: an invite / allowlisted email at [app.keeljs.cloud](https://app.keeljs.cloud)
|
|
34
|
+
during private alpha
|
|
35
|
+
|
|
36
|
+
## 1. Create an app
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm create keeljs@latest my-app # full-stack "app" preset (default)
|
|
40
|
+
# npm create keeljs@latest my-api -- --preset api
|
|
41
|
+
# npm create keeljs@latest my-saas -- --preset saas
|
|
42
|
+
# npm create keeljs@latest bare -- --preset minimal
|
|
43
|
+
cd my-app
|
|
44
|
+
npm install
|
|
45
|
+
cp .env.example .env # if the kit didn't already
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
| Preset | Use when |
|
|
49
|
+
|--------|----------|
|
|
50
|
+
| `minimal` | Hello-world / learning — routes, a view, Tailwind. No database. |
|
|
51
|
+
| `api` | JSON API — models, migrations, token auth, OpenAPI, tests. |
|
|
52
|
+
| `app` *(default)* | Product with views, sessions, register/login, password reset, 2FA. |
|
|
53
|
+
| `saas` | Multi-tenant product — teams, roles, invitations, billing. |
|
|
54
|
+
|
|
55
|
+
Templates live **inside** `@shaferllc/keel`, so the kit version matches the
|
|
56
|
+
framework version you just installed. Details: [Starter kits](./starter-kits.md).
|
|
57
|
+
|
|
58
|
+
## 2. Run it locally
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npm run migrate # if the preset has a database (api / app / saas)
|
|
62
|
+
npm run dev # http://localhost:3000 — Node + local SQLite
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Useful next commands:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npm run keel -- routes # what is mounted
|
|
69
|
+
npm run keel -- make:controller Post # scaffold, then wire a route
|
|
70
|
+
npm test
|
|
71
|
+
npm run typecheck
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Local tip: `DB_CONNECTION` defaults to a SQLite file. Switching drivers later is
|
|
75
|
+
config only — see [Database](./database.md) and [Starter kits](./starter-kits.md).
|
|
76
|
+
|
|
77
|
+
For a guided first hour inside the codebase (routes, controllers, views, config),
|
|
78
|
+
read [Getting Started](./getting-started.md).
|
|
79
|
+
|
|
80
|
+
## 3. Optional — AI agents (local)
|
|
81
|
+
|
|
82
|
+
Keel is designed to be written with an agent. Point Cursor / Claude Code at the
|
|
83
|
+
MCP server that ships with the package:
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"mcpServers": {
|
|
88
|
+
"keel": {
|
|
89
|
+
"command": "npx",
|
|
90
|
+
"args": ["-y", "keel-mcp"]
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Then have the agent call `keel_overview` first. It can search docs, look up the
|
|
97
|
+
public API, and scaffold controllers/jobs/… without inventing imports.
|
|
98
|
+
|
|
99
|
+
Full map: [Building with AI](./ai.md).
|
|
100
|
+
|
|
101
|
+
## 4. Deploy yourself (Cloudflare Workers)
|
|
102
|
+
|
|
103
|
+
Every kit includes `wrangler.jsonc`, a `worker.ts` entry, and `npm run deploy`.
|
|
104
|
+
You own the Cloudflare account and the hostname.
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# one-time
|
|
108
|
+
npx wrangler login
|
|
109
|
+
npx wrangler d1 create my-app # paste database_id into wrangler.jsonc
|
|
110
|
+
|
|
111
|
+
# ship
|
|
112
|
+
npm run deploy # css:build + wrangler deploy
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Migrations against remote D1 use the HTTP driver from your laptop / CI — the
|
|
116
|
+
binding only exists inside the Worker. Set Cloudflare API credentials as
|
|
117
|
+
documented in [Database](./database.md) (D1 HTTP) and your kit’s README.
|
|
118
|
+
|
|
119
|
+
Edge preview without deploying:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
npm run dev:edge # wrangler + local D1
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Hosting helpers (hostname utils, SQL dump, secrets encryption) live in
|
|
126
|
+
[`@shaferllc/keel/hosting`](./hosting.md) if you build your own control plane.
|
|
127
|
+
|
|
128
|
+
## 5. Optional — Keel Cloud
|
|
129
|
+
|
|
130
|
+
[Keel Cloud](https://app.keeljs.cloud) is a hosted control plane: pick a preset,
|
|
131
|
+
edit real source, preview and publish Workers for you, vault secrets, and export
|
|
132
|
+
git + SQL anytime. Free tier is limited (typically one site); Pro adds more sites
|
|
133
|
+
and custom domains.
|
|
134
|
+
|
|
135
|
+
Use Cloud when you want the platform to own deploys and hostnames. Skip it when
|
|
136
|
+
you already have Cloudflare / your own pipeline (§4).
|
|
137
|
+
|
|
138
|
+
### Sign up and mint a token
|
|
139
|
+
|
|
140
|
+
1. Open [app.keeljs.cloud](https://app.keeljs.cloud) (invite code or allowlisted
|
|
141
|
+
email during alpha).
|
|
142
|
+
2. Create a personal access token at **`/tokens`**. The plaintext looks like
|
|
143
|
+
`keel_<selector>.<verifier>` — copy it once.
|
|
144
|
+
3. Wire it into your MCP client (same `keel-mcp` binary as local):
|
|
145
|
+
|
|
146
|
+
```json
|
|
147
|
+
{
|
|
148
|
+
"mcpServers": {
|
|
149
|
+
"keel": {
|
|
150
|
+
"command": "npx",
|
|
151
|
+
"args": ["-y", "keel-mcp"],
|
|
152
|
+
"env": {
|
|
153
|
+
"KEEL_CLOUD_TOKEN": "keel_….…",
|
|
154
|
+
"KEEL_CLOUD_URL": "https://app.keeljs.cloud"
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Reload MCP. When the token is set, `keel_cloud_*` tools appear alongside the
|
|
162
|
+
docs tools. The token binds to your **first team**.
|
|
163
|
+
|
|
164
|
+
### Agent loop on Cloud
|
|
165
|
+
|
|
166
|
+
1. `keel_cloud_create_site { name: "Acme", preset: "app" }`
|
|
167
|
+
2. Edit files at the returned `storage_path` (real Keel app + git)
|
|
168
|
+
3. `keel_cloud_set_secret` for anything the Worker needs at runtime
|
|
169
|
+
4. `keel_cloud_preview { site_id }` — iterate freely
|
|
170
|
+
5. `keel_cloud_publish { site_id, confirm: true }` — only after you approve
|
|
171
|
+
6. Optional Pro: `keel_cloud_set_custom_domain { hostname, attach: true }`
|
|
172
|
+
7. Escape hatch anytime: `keel_cloud_export` + `keel_cloud_export_sql`
|
|
173
|
+
|
|
174
|
+
You can also drive the same flow from the dashboard at `/sites`. Billing for Pro
|
|
175
|
+
is at `/billing` (or `keel_cloud_billing` / `_checkout` / `_portal` via MCP).
|
|
176
|
+
|
|
177
|
+
Tool reference: [Building with AI](./ai.md#the-mcp-server).
|
|
178
|
+
|
|
179
|
+
## Which path should I pick?
|
|
180
|
+
|
|
181
|
+
| Goal | Path |
|
|
182
|
+
|------|------|
|
|
183
|
+
| Learn Keel / ship a side project on your CF account | §§1–4 |
|
|
184
|
+
| Build with an agent in your IDE, deploy yourself | §§1–4 + §3 |
|
|
185
|
+
| Let the platform host preview/prod + secrets + export | §§1–2 + §5 (Cloud creates the app for you) |
|
|
186
|
+
| Multi-tenant SaaS with billing | Preset `saas`, then §4 or §5 |
|
|
187
|
+
|
|
188
|
+
Cloud **create_site** scaffolds a kit the same way `create-keeljs` does — you do
|
|
189
|
+
not need both for the same app. Use `create-keeljs` for apps you own end-to-end;
|
|
190
|
+
use Cloud when you want hosted preview/publish under `*.keeljs.cloud`.
|
|
191
|
+
|
|
192
|
+
## Where next
|
|
193
|
+
|
|
194
|
+
- [Getting Started](./getting-started.md) — first route, controller, view
|
|
195
|
+
- [Starter kits](./starter-kits.md) — presets and the Node/edge seam
|
|
196
|
+
- [Building with AI](./ai.md) — MCP tools (local + Cloud)
|
|
197
|
+
- [Hosting](./hosting.md) — Cloudflare / dump / secrets primitives
|
|
198
|
+
- [Accounts](./accounts.md) · [Teams](./teams.md) · [Billing](./billing.md) — what
|
|
199
|
+
`app` / `saas` already mount
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
10
203
|
---
|
|
11
204
|
|
|
12
205
|
<!-- source: docs/getting-started.md -->
|
|
@@ -28,32 +221,20 @@ Keel targets modern Node and web-standard APIs, so a current runtime matters —
|
|
|
28
221
|
|
|
29
222
|
## Install
|
|
30
223
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
that already exists. See [Architecture](./architecture.md#two-repos-library-and-starter)
|
|
35
|
-
for why it's split this way.
|
|
36
|
-
|
|
37
|
-
### From the starter (recommended)
|
|
38
|
-
|
|
39
|
-
The fastest route to a running app is the starter — a working skeleton with the
|
|
40
|
-
folders, config, and scripts already wired:
|
|
224
|
+
The fastest path to a running app is the generator — it copies a curated kit
|
|
225
|
+
from the same `@shaferllc/keel` version you install, so the template cannot lag
|
|
226
|
+
the framework:
|
|
41
227
|
|
|
42
228
|
```bash
|
|
43
|
-
|
|
229
|
+
npm create keeljs@latest my-app
|
|
44
230
|
cd my-app
|
|
45
231
|
npm install
|
|
232
|
+
npm run dev # http://localhost:3000
|
|
46
233
|
```
|
|
47
234
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
A fresh checkout ships with a working `.env`. To start from the template
|
|
52
|
-
instead:
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
cp .env.example .env
|
|
56
|
-
```
|
|
235
|
+
For the full journey (presets, Cloudflare deploy, optional Keel Cloud + MCP),
|
|
236
|
+
see **[From install to deploy](./from-install-to-deploy.md)**. Kit details:
|
|
237
|
+
[Starter kits](./starter-kits.md).
|
|
57
238
|
|
|
58
239
|
### Into an existing app
|
|
59
240
|
|
|
@@ -70,22 +251,24 @@ import { Application, Router, config } from "@shaferllc/keel/core";
|
|
|
70
251
|
```
|
|
71
252
|
|
|
72
253
|
You supply the four convention folders yourself — `app/`, `config/`, `routes/`,
|
|
73
|
-
`bootstrap/` — plus an entry that calls `createApplication()`.
|
|
254
|
+
`bootstrap/` — plus an entry that calls `createApplication()`. A generated kit’s
|
|
74
255
|
`bootstrap/app.ts` is the reference; copy it and trim to taste.
|
|
75
256
|
|
|
76
257
|
### Hacking on the framework itself
|
|
77
258
|
|
|
78
|
-
To work on Keel proper, clone the framework repo
|
|
79
|
-
can run directly:
|
|
259
|
+
To work on Keel proper, clone the framework repo:
|
|
80
260
|
|
|
81
261
|
```bash
|
|
82
262
|
git clone https://github.com/shaferllc/keel.git
|
|
83
263
|
cd keel
|
|
84
264
|
npm install
|
|
85
|
-
npm
|
|
86
|
-
npm run
|
|
265
|
+
npm test
|
|
266
|
+
npm run typecheck
|
|
87
267
|
```
|
|
88
268
|
|
|
269
|
+
Generate a disposable app against your checkout with
|
|
270
|
+
`npm create keeljs@latest …` and point its dependency at `file:../keel`.
|
|
271
|
+
|
|
89
272
|
## Run the server
|
|
90
273
|
|
|
91
274
|
```bash
|
|
@@ -280,9 +463,10 @@ unsure what's mounted. [The Console](./console.md) lists every command.
|
|
|
280
463
|
## Where to go next
|
|
281
464
|
|
|
282
465
|
You now have the shape of a Keel app: routes point at controllers, controllers
|
|
283
|
-
render views and read config, and the console scaffolds the pieces.
|
|
284
|
-
guides pick up from here:
|
|
466
|
+
render views and read config, and the console scaffolds the pieces.
|
|
285
467
|
|
|
468
|
+
- **[From install to deploy](./from-install-to-deploy.md)** — presets, Cloudflare,
|
|
469
|
+
optional Keel Cloud + MCP
|
|
286
470
|
- [Architecture](./architecture.md) — how boot, the container, and the request
|
|
287
471
|
lifecycle fit together
|
|
288
472
|
- [The Service Container](./container.md) — how dependency injection works
|
|
@@ -297,6 +481,7 @@ guides pick up from here:
|
|
|
297
481
|
the active-record layer on top of it
|
|
298
482
|
- [Configuration](./configuration.md) and [The Console](./console.md) — settings
|
|
299
483
|
and commands
|
|
484
|
+
- [Building with AI](./ai.md) — MCP docs + Cloud tools
|
|
300
485
|
|
|
301
486
|
When something isn't documented, open the source — the whole framework is a few
|
|
302
487
|
hundred readable lines in `src/core/`, and [Built on Hono](./hono.md) explains
|
|
@@ -304,6 +489,116 @@ what you inherit from the layer underneath.
|
|
|
304
489
|
|
|
305
490
|
|
|
306
491
|
|
|
492
|
+
---
|
|
493
|
+
|
|
494
|
+
<!-- source: docs/starter-kits.md -->
|
|
495
|
+
|
|
496
|
+
# Starter kits
|
|
497
|
+
|
|
498
|
+
```bash
|
|
499
|
+
npm create keeljs@latest my-app -- --preset saas
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
Four curated applications. Each is a complete, working app — not a scaffold you have
|
|
503
|
+
to finish. For the full path from this command through Cloudflare or Keel Cloud,
|
|
504
|
+
see [From install to deploy](./from-install-to-deploy.md).
|
|
505
|
+
|
|
506
|
+
| Preset | What you get |
|
|
507
|
+
| --- | --- |
|
|
508
|
+
| `minimal` | Routes, a controller, a JSX view, Tailwind. No database. |
|
|
509
|
+
| `api` | JSON only — models, migrations, validation, tests. No views. |
|
|
510
|
+
| `app` *(default)* | Full-stack: views, sessions, register/login, password reset, two-factor. |
|
|
511
|
+
| `saas` | `app` plus teams, roles, invitations, billing, and multi-tenancy. |
|
|
512
|
+
|
|
513
|
+
## Pick a kit
|
|
514
|
+
|
|
515
|
+
```bash
|
|
516
|
+
npm create keeljs@latest my-app # app (default)
|
|
517
|
+
npm create keeljs@latest my-api -- --preset api
|
|
518
|
+
npm create keeljs@latest my-saas -- --preset saas
|
|
519
|
+
npm create keeljs@latest bare -- --preset minimal
|
|
520
|
+
cd my-app && npm install && npm run dev
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
Then open `http://localhost:3000`. The SaaS kit already has a team switcher,
|
|
524
|
+
invites, and a billing stub wired through [teams](./teams.md) and
|
|
525
|
+
[billing](./billing.md) — start by editing `app/Models` and `routes/web.ts`.
|
|
526
|
+
|
|
527
|
+
## Every database, Cloudflare first
|
|
528
|
+
|
|
529
|
+
Each kit ships with all four drivers wired. Switching is `DB_CONNECTION` and nothing
|
|
530
|
+
else — no model or query changes, because they talk to a `Connection`, not a driver.
|
|
531
|
+
|
|
532
|
+
| | |
|
|
533
|
+
| --- | --- |
|
|
534
|
+
| **D1** | The default for deploys. Inside the Worker Keel uses the binding; migrations and scripts reach the same database over [the HTTP API](./database.md), so `keel migrate` works from your laptop and from CI. |
|
|
535
|
+
| **SQLite** (libSQL) | A local file. What `npm run dev` uses — no account, no wrangler. |
|
|
536
|
+
| **Turso** | libSQL over the network. |
|
|
537
|
+
| **Postgres** | For when you want it. |
|
|
538
|
+
|
|
539
|
+
Local and production are both SQLite dialects, so one schema and one set of
|
|
540
|
+
migrations serve both.
|
|
541
|
+
|
|
542
|
+
```bash
|
|
543
|
+
npm run dev # Node, SQLite file, no setup
|
|
544
|
+
npm run dev:edge # wrangler, local D1
|
|
545
|
+
npm run deploy # wrangler deploy
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
To deploy:
|
|
549
|
+
|
|
550
|
+
```bash
|
|
551
|
+
wrangler d1 create my-app # paste the id into wrangler.jsonc
|
|
552
|
+
npm run deploy
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
## What's in the box
|
|
556
|
+
|
|
557
|
+
`app` and `saas` mount [accounts](./accounts.md), so password reset, email
|
|
558
|
+
verification, and two-factor already work — the flows live in the framework, tested
|
|
559
|
+
once, rather than being copy-pasted into each new app. `saas` also mounts
|
|
560
|
+
[teams](./teams.md) and [billing](./billing.md).
|
|
561
|
+
|
|
562
|
+
In `saas`, a tenant-owned model is one word:
|
|
563
|
+
|
|
564
|
+
```ts
|
|
565
|
+
import { TenantModel } from "@shaferllc/keel/teams";
|
|
566
|
+
|
|
567
|
+
class Project extends TenantModel {
|
|
568
|
+
static table = "projects";
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
await Project.all(); // only the current team's. Always.
|
|
572
|
+
await Project.create({ name: "Hi" }); // stamped with the current team
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
Another team's project isn't merely hidden from a list — `Project.find(id)` returns
|
|
576
|
+
`null`. You never write `.where("team_id", …)`, which is what makes it impossible to
|
|
577
|
+
forget.
|
|
578
|
+
|
|
579
|
+
## Why a generator, and not a template repo
|
|
580
|
+
|
|
581
|
+
Because a second repo rots. The old starter sat pinned to `0.78.2` while the
|
|
582
|
+
framework was on `0.79.0`, and nothing noticed.
|
|
583
|
+
|
|
584
|
+
The templates live **inside the framework package**, so the version a kit is
|
|
585
|
+
generated from is, by construction, the version it was written for. And CI generates
|
|
586
|
+
all four on every push, then typechecks, migrates, boots, serves a request, bundles
|
|
587
|
+
the Worker, and runs their tests — so a breaking change fails in the pull request
|
|
588
|
+
that caused it, not in your `npm create` three weeks later.
|
|
589
|
+
|
|
590
|
+
## The Node/edge seam
|
|
591
|
+
|
|
592
|
+
Each kit has two provider lists. `bootstrap/providers.ts` runs under Node;
|
|
593
|
+
`bootstrap/providers.edge.ts` runs in the Worker and deliberately **omits the
|
|
594
|
+
database provider** — it reaches for `pg`, which needs `net`/`tls`, and wrangler
|
|
595
|
+
cannot bundle a TCP driver for the edge. `worker.ts` binds D1 before the app boots,
|
|
596
|
+
so nothing on the edge needs to open a connection.
|
|
597
|
+
|
|
598
|
+
If you add a provider that touches a Node-only module, add it to the Node list only.
|
|
599
|
+
|
|
600
|
+
|
|
601
|
+
|
|
307
602
|
---
|
|
308
603
|
|
|
309
604
|
<!-- source: docs/architecture.md -->
|
|
@@ -4669,8 +4964,9 @@ AI-facing surface: an MCP server, machine-readable docs (`llms.txt` /
|
|
|
4669
4964
|
`llms-full.txt`), an agent playbook (`AGENTS.md`), and code generators an agent
|
|
4670
4965
|
can drive directly.
|
|
4671
4966
|
|
|
4672
|
-
If you only read one thing:
|
|
4673
|
-
|
|
4967
|
+
If you only read one thing: follow
|
|
4968
|
+
[From install to deploy](./from-install-to-deploy.md), then point your agent at
|
|
4969
|
+
the [MCP server](#the-mcp-server) and have it call `keel_overview` first.
|
|
4674
4970
|
|
|
4675
4971
|
## Why this exists
|
|
4676
4972
|
|
|
@@ -4726,18 +5022,23 @@ package, so it always matches your installed version.
|
|
|
4726
5022
|
| `keel_scaffold` | Generate a controller/provider/middleware/factory/seeder/job/notification/transformer stub. Returns code + target path — it does **not** write to disk. |
|
|
4727
5023
|
|
|
4728
5024
|
When `KEEL_CLOUD_TOKEN` (and optional `KEEL_CLOUD_URL`) is set, Cloud tools are
|
|
4729
|
-
also registered
|
|
5025
|
+
also registered. Create a token at `/tokens` on the control plane — the plaintext
|
|
5026
|
+
looks like `keel_<selector>.<verifier>`.
|
|
4730
5027
|
|
|
4731
5028
|
| Tool | What it does |
|
|
4732
5029
|
|------|--------------|
|
|
4733
|
-
| `keel_cloud_me` | Authenticated Cloud user |
|
|
4734
|
-
| `
|
|
5030
|
+
| `keel_cloud_me` | Authenticated Cloud user (plan, site limit, team) |
|
|
5031
|
+
| `keel_cloud_billing` | Team plan / limits / owner flag |
|
|
5032
|
+
| `keel_cloud_billing_checkout` / `_portal` | Stripe Checkout or Customer Portal URL (owner) |
|
|
5033
|
+
| `keel_cloud_list_sites` / `keel_cloud_get_site` | List or fetch a site (`storage_path`, hostnames, git) |
|
|
4735
5034
|
| `keel_cloud_create_site` | Create from preset (`minimal` \| `api` \| `app` \| `saas`) |
|
|
5035
|
+
| `keel_cloud_delete_site` / `keel_cloud_restore_site` | Soft-delete (confirm) / restore |
|
|
4736
5036
|
| `keel_cloud_preview` | Deploy preview Worker |
|
|
4737
5037
|
| `keel_cloud_publish` | Publish production — requires `confirm: true` |
|
|
4738
|
-
| `
|
|
4739
|
-
| `
|
|
4740
|
-
| `
|
|
5038
|
+
| `keel_cloud_deploys` | Deploy history + logs |
|
|
5039
|
+
| `keel_cloud_list_secrets` / `keel_cloud_set_secret` / `keel_cloud_delete_secret` | Vault keys (values never returned) |
|
|
5040
|
+
| `keel_cloud_set_custom_domain` / `keel_cloud_clear_custom_domain` | Pro custom hostname (+ optional attach) |
|
|
5041
|
+
| `keel_cloud_export` / `keel_cloud_export_sql` | Export manifest / portable `.sql` dump |
|
|
4741
5042
|
|
|
4742
5043
|
```json
|
|
4743
5044
|
{
|
|
@@ -4746,7 +5047,7 @@ also registered:
|
|
|
4746
5047
|
"command": "npx",
|
|
4747
5048
|
"args": ["-y", "keel-mcp"],
|
|
4748
5049
|
"env": {
|
|
4749
|
-
"KEEL_CLOUD_TOKEN": "
|
|
5050
|
+
"KEEL_CLOUD_TOKEN": "keel_….…",
|
|
4750
5051
|
"KEEL_CLOUD_URL": "https://app.keeljs.cloud"
|
|
4751
5052
|
}
|
|
4752
5053
|
}
|
|
@@ -4754,6 +5055,8 @@ also registered:
|
|
|
4754
5055
|
}
|
|
4755
5056
|
```
|
|
4756
5057
|
|
|
5058
|
+
The token binds to the user's **first team**. Switch teams in the dashboard before
|
|
5059
|
+
minting a token if you need a different team context.
|
|
4757
5060
|
### Resources
|
|
4758
5061
|
|
|
4759
5062
|
- `keel://overview` — the same orientation text as `keel_overview`
|
|
@@ -4772,8 +5075,11 @@ also registered:
|
|
|
4772
5075
|
|
|
4773
5076
|
1. `keel_cloud_create_site { name: "Acme", preset: "app" }`
|
|
4774
5077
|
2. Edit the returned `storage_path` (real Keel app + git)
|
|
4775
|
-
3. `
|
|
4776
|
-
4. `
|
|
5078
|
+
3. `keel_cloud_set_secret` for env the Worker needs
|
|
5079
|
+
4. `keel_cloud_preview { site_id }`
|
|
5080
|
+
5. `keel_cloud_publish { site_id, confirm: true }` after the user approves
|
|
5081
|
+
6. Optional Pro: `keel_cloud_set_custom_domain { hostname, attach: true }`
|
|
5082
|
+
7. Escape hatch anytime: `keel_cloud_export` + `keel_cloud_export_sql`
|
|
4777
5083
|
|
|
4778
5084
|
## `llms.txt` and `llms-full.txt`
|
|
4779
5085
|
|
|
@@ -17947,115 +18253,6 @@ const gitlab = social.driver(
|
|
|
17947
18253
|
|
|
17948
18254
|
|
|
17949
18255
|
|
|
17950
|
-
---
|
|
17951
|
-
|
|
17952
|
-
<!-- source: docs/starter-kits.md -->
|
|
17953
|
-
|
|
17954
|
-
# Starter kits
|
|
17955
|
-
|
|
17956
|
-
```bash
|
|
17957
|
-
npm create keeljs@latest my-app -- --preset saas
|
|
17958
|
-
```
|
|
17959
|
-
|
|
17960
|
-
Four curated applications. Each is a complete, working app — not a scaffold you have
|
|
17961
|
-
to finish.
|
|
17962
|
-
|
|
17963
|
-
| Preset | What you get |
|
|
17964
|
-
| --- | --- |
|
|
17965
|
-
| `minimal` | Routes, a controller, a JSX view, Tailwind. No database. |
|
|
17966
|
-
| `api` | JSON only — models, migrations, validation, tests. No views. |
|
|
17967
|
-
| `app` *(default)* | Full-stack: views, sessions, register/login, password reset, two-factor. |
|
|
17968
|
-
| `saas` | `app` plus teams, roles, invitations, billing, and multi-tenancy. |
|
|
17969
|
-
|
|
17970
|
-
## Pick a kit
|
|
17971
|
-
|
|
17972
|
-
```bash
|
|
17973
|
-
npm create keeljs@latest my-app # app (default)
|
|
17974
|
-
npm create keeljs@latest my-api -- --preset api
|
|
17975
|
-
npm create keeljs@latest my-saas -- --preset saas
|
|
17976
|
-
npm create keeljs@latest bare -- --preset minimal
|
|
17977
|
-
cd my-app && npm install && npm run dev
|
|
17978
|
-
```
|
|
17979
|
-
|
|
17980
|
-
Then open `http://localhost:3000`. The SaaS kit already has a team switcher,
|
|
17981
|
-
invites, and a billing stub wired through [teams](./teams.md) and
|
|
17982
|
-
[billing](./billing.md) — start by editing `app/Models` and `routes/web.ts`.
|
|
17983
|
-
|
|
17984
|
-
## Every database, Cloudflare first
|
|
17985
|
-
|
|
17986
|
-
Each kit ships with all four drivers wired. Switching is `DB_CONNECTION` and nothing
|
|
17987
|
-
else — no model or query changes, because they talk to a `Connection`, not a driver.
|
|
17988
|
-
|
|
17989
|
-
| | |
|
|
17990
|
-
| --- | --- |
|
|
17991
|
-
| **D1** | The default for deploys. Inside the Worker Keel uses the binding; migrations and scripts reach the same database over [the HTTP API](./database.md), so `keel migrate` works from your laptop and from CI. |
|
|
17992
|
-
| **SQLite** (libSQL) | A local file. What `npm run dev` uses — no account, no wrangler. |
|
|
17993
|
-
| **Turso** | libSQL over the network. |
|
|
17994
|
-
| **Postgres** | For when you want it. |
|
|
17995
|
-
|
|
17996
|
-
Local and production are both SQLite dialects, so one schema and one set of
|
|
17997
|
-
migrations serve both.
|
|
17998
|
-
|
|
17999
|
-
```bash
|
|
18000
|
-
npm run dev # Node, SQLite file, no setup
|
|
18001
|
-
npm run dev:edge # wrangler, local D1
|
|
18002
|
-
npm run deploy # wrangler deploy
|
|
18003
|
-
```
|
|
18004
|
-
|
|
18005
|
-
To deploy:
|
|
18006
|
-
|
|
18007
|
-
```bash
|
|
18008
|
-
wrangler d1 create my-app # paste the id into wrangler.jsonc
|
|
18009
|
-
npm run deploy
|
|
18010
|
-
```
|
|
18011
|
-
|
|
18012
|
-
## What's in the box
|
|
18013
|
-
|
|
18014
|
-
`app` and `saas` mount [accounts](./accounts.md), so password reset, email
|
|
18015
|
-
verification, and two-factor already work — the flows live in the framework, tested
|
|
18016
|
-
once, rather than being copy-pasted into each new app. `saas` also mounts
|
|
18017
|
-
[teams](./teams.md) and [billing](./billing.md).
|
|
18018
|
-
|
|
18019
|
-
In `saas`, a tenant-owned model is one word:
|
|
18020
|
-
|
|
18021
|
-
```ts
|
|
18022
|
-
import { TenantModel } from "@shaferllc/keel/teams";
|
|
18023
|
-
|
|
18024
|
-
class Project extends TenantModel {
|
|
18025
|
-
static table = "projects";
|
|
18026
|
-
}
|
|
18027
|
-
|
|
18028
|
-
await Project.all(); // only the current team's. Always.
|
|
18029
|
-
await Project.create({ name: "Hi" }); // stamped with the current team
|
|
18030
|
-
```
|
|
18031
|
-
|
|
18032
|
-
Another team's project isn't merely hidden from a list — `Project.find(id)` returns
|
|
18033
|
-
`null`. You never write `.where("team_id", …)`, which is what makes it impossible to
|
|
18034
|
-
forget.
|
|
18035
|
-
|
|
18036
|
-
## Why a generator, and not a template repo
|
|
18037
|
-
|
|
18038
|
-
Because a second repo rots. The old starter sat pinned to `0.78.2` while the
|
|
18039
|
-
framework was on `0.79.0`, and nothing noticed.
|
|
18040
|
-
|
|
18041
|
-
The templates live **inside the framework package**, so the version a kit is
|
|
18042
|
-
generated from is, by construction, the version it was written for. And CI generates
|
|
18043
|
-
all four on every push, then typechecks, migrates, boots, serves a request, bundles
|
|
18044
|
-
the Worker, and runs their tests — so a breaking change fails in the pull request
|
|
18045
|
-
that caused it, not in your `npm create` three weeks later.
|
|
18046
|
-
|
|
18047
|
-
## The Node/edge seam
|
|
18048
|
-
|
|
18049
|
-
Each kit has two provider lists. `bootstrap/providers.ts` runs under Node;
|
|
18050
|
-
`bootstrap/providers.edge.ts` runs in the Worker and deliberately **omits the
|
|
18051
|
-
database provider** — it reaches for `pg`, which needs `net`/`tls`, and wrangler
|
|
18052
|
-
cannot bundle a TCP driver for the edge. `worker.ts` binds D1 before the app boots,
|
|
18053
|
-
so nothing on the edge needs to open a connection.
|
|
18054
|
-
|
|
18055
|
-
If you add a provider that touches a Node-only module, add it to the Node list only.
|
|
18056
|
-
|
|
18057
|
-
|
|
18058
|
-
|
|
18059
18256
|
---
|
|
18060
18257
|
|
|
18061
18258
|
<!-- source: docs/static-files.md -->
|
package/llms.txt
CHANGED
|
@@ -30,6 +30,7 @@ Userland imports everything from `@shaferllc/keel/core`.
|
|
|
30
30
|
- [Errors & Exceptions](https://github.com/shaferllc/keel/blob/main/docs/errors.md): Throw an exception anywhere — a handler, middleware, or a service deep in the container — and Keel's HTTP kernel turns it into the right response.
|
|
31
31
|
- [Events](https://github.com/shaferllc/keel/blob/main/docs/events.md): A tiny event emitter for decoupling — fire an event in one place, handle it in another.
|
|
32
32
|
- [Factories & Seeders](https://github.com/shaferllc/keel/blob/main/docs/factories.md): Populate the database with realistic fixtures for tests and demos.
|
|
33
|
+
- [From install to deploy](https://github.com/shaferllc/keel/blob/main/docs/from-install-to-deploy.md): One path from zero to a live Keel app — locally, on Cloudflare yourself, or on Keel Cloud with an AI agent.
|
|
33
34
|
- [Gates](https://github.com/shaferllc/keel/blob/main/docs/gates.md): Keel Gates is a signup gate for private alpha / waitlist apps: an email allowlist, invite codes with use limits and expiry, and a single check that answers "may this person register?".
|
|
34
35
|
- [Getting Started](https://github.com/shaferllc/keel/blob/main/docs/getting-started.md): Keel is a house framework for Node.js — a small, legible MVC layer over Hono.
|
|
35
36
|
- [Hashing & Encryption](https://github.com/shaferllc/keel/blob/main/docs/hashing.md): Password hashing and value encryption, both built on the Web Crypto API — so they run identically on Node and the edge, with no native bindings (no bcrypt to compile).
|
package/package.json
CHANGED