@abloatai/ablo 0.37.0 → 0.38.0
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 +3 -3
- package/CHANGELOG.md +162 -92
- package/README.md +86 -21
- package/dist/ai-sdk.d.ts +2 -0
- package/dist/ai-sdk.d.ts.map +1 -0
- package/dist/ai-sdk.js +2 -0
- package/dist/ai-sdk.js.map +1 -0
- package/docs/agents.md +59 -9
- package/docs/api-keys.md +51 -27
- package/docs/branch-development.md +392 -0
- package/docs/cli.md +50 -42
- package/docs/data-sources.md +11 -0
- package/docs/deployment.md +20 -19
- package/docs/examples/ai-sdk-tool.md +25 -52
- package/docs/how-it-works.md +3 -2
- package/docs/index.md +7 -3
- package/docs/integration-guide.md +6 -13
- package/docs/integrations/inngest.md +258 -0
- package/docs/integrations/temporal.md +187 -0
- package/docs/integrations.md +54 -0
- package/docs/migration.md +4 -4
- package/docs/projects.md +1 -1
- package/docs/quickstart.md +30 -22
- package/docs/webhooks.md +4 -4
- package/llms.txt +20 -18
- package/package.json +15 -3
package/docs/api-keys.md
CHANGED
|
@@ -27,6 +27,11 @@ Pick your row:
|
|
|
27
27
|
|
|
28
28
|
That's the whole story: one knob, filled by audience.
|
|
29
29
|
|
|
30
|
+
The `mk_` credential created by `ablo login` is different: it is a CLI
|
|
31
|
+
control-plane credential, not an application API key. It can manage projects
|
|
32
|
+
and branches and exchange for a branch-bound runtime key. Do not pass it to
|
|
33
|
+
`Ablo(...)` or put it in `ABLO_API_KEY`.
|
|
34
|
+
|
|
30
35
|
**Coming from Stripe? It's the same key model, same prefixes:**
|
|
31
36
|
|
|
32
37
|
| Stripe | Ablo | Where it goes |
|
|
@@ -36,7 +41,14 @@ That's the whole story: one knob, filled by audience.
|
|
|
36
41
|
| restricted `rk_` (granular) | `rk_` | scoped agents (`agents.create({ can })`) |
|
|
37
42
|
| ephemeral key (client, customer-scoped) | `ek_` | per-user browser sessions (`sessions.create({ user, can })`) |
|
|
38
43
|
|
|
39
|
-
|
|
44
|
+
Ablo also has one credential class that Stripe does not need:
|
|
45
|
+
|
|
46
|
+
| Prefix | Purpose | Mode | Stored where |
|
|
47
|
+
|---|---|---|---|
|
|
48
|
+
| `mk_` | project and branch management | none | CLI credential store or `ABLO_MANAGEMENT_KEY` |
|
|
49
|
+
|
|
50
|
+
Trust class lives in the prefix too — `sk_test_` / `sk_live_` — exactly like Stripe.
|
|
51
|
+
It does not select a branch; the immutable server-side binding does that. The
|
|
40
52
|
`apiKey` resolver fetching an `ek_` is Ablo's ephemeral-key flow: server mints, client holds.
|
|
41
53
|
|
|
42
54
|
**Why a function for browser writes?** Anything you ship to a browser must be public, and a
|
|
@@ -91,21 +103,28 @@ cannot reach any control-plane operation. The moment the browser needs to write
|
|
|
91
103
|
on a specific user's behalf, mint a short-lived `ek_` user session from your
|
|
92
104
|
backend instead (see the Sessions guide).
|
|
93
105
|
|
|
94
|
-
##
|
|
106
|
+
## Branches and production
|
|
95
107
|
|
|
96
|
-
|
|
108
|
+
A branch is your project at full strength over its own rows: the same models,
|
|
109
|
+
the same schema, the same claims and the same rules production runs.
|
|
97
110
|
|
|
98
|
-
|
|
99
|
-
|
|
111
|
+
Production is the project's root branch. Development branches are isolated
|
|
112
|
+
children, and a key's immutable branch binding decides which rows, schema,
|
|
113
|
+
claims, and log it can reach:
|
|
114
|
+
|
|
115
|
+
- `sk_test_…` — a key bound to a development branch. Its reads and
|
|
116
|
+
writes are invisible to production and to other branches.
|
|
100
117
|
- `sk_live_…` — a key against your live data.
|
|
101
118
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
119
|
+
`npx ablo dev` derives a branch from Git, ensures the matching child, and mints
|
|
120
|
+
an expiring `sk_test_` key for it. The credential carries the immutable branch
|
|
121
|
+
id; changing a slug in a request cannot change its authority. A child receives
|
|
122
|
+
the parent's active schema when it is created and owns its artifact after that.
|
|
123
|
+
A schema change reaches production only through the reviewed live-key path in
|
|
124
|
+
[Deployment](./deployment.md).
|
|
125
|
+
|
|
126
|
+
The shared default sandbox is no longer part of the development workflow.
|
|
127
|
+
Branch identity is required for newly provisioned CLI and runtime credentials.
|
|
109
128
|
|
|
110
129
|
## Scopes
|
|
111
130
|
|
|
@@ -114,25 +133,30 @@ only what its job needs. A secret key with **no scopes** has full org authority
|
|
|
114
133
|
(the default for a `sk_live_` backend key); a key with a non-empty scope set is
|
|
115
134
|
restricted to exactly those grants:
|
|
116
135
|
|
|
117
|
-
- `schema:push` — author the
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
- `
|
|
122
|
-
|
|
136
|
+
- `schema:push` — author the schema artifact on the key's bound plane
|
|
137
|
+
(`ablo push`, `ablo dev`). A production push is high-risk because it changes
|
|
138
|
+
the live contract; a child push remains inside that branch. A
|
|
139
|
+
full-authority key has it implicitly; a restricted key needs it explicitly.
|
|
140
|
+
- `project:manage` — list, create, and rename projects.
|
|
141
|
+
- `branch:manage` — list, create, and delete child branches and mint their
|
|
142
|
+
temporary credentials.
|
|
143
|
+
|
|
144
|
+
Both management scopes are explicit grants on `mk_` credentials. Runtime
|
|
145
|
+
`sk_`, `rk_`, `pk_`, and `ek_` credentials cannot become management
|
|
146
|
+
credentials through an empty scope set or a CLI fallback.
|
|
123
147
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
schema too. Hand data-only keys to embedded apps and CI agents; reserve
|
|
128
|
-
schema-authoring keys for the developer running `ablo dev`.
|
|
148
|
+
Branch binding remains an authority boundary even when a key has no granular
|
|
149
|
+
scope strings: a temporary child key can act only inside that child. It cannot
|
|
150
|
+
manage siblings or gain root authority.
|
|
129
151
|
|
|
130
152
|
### `ablo dev`
|
|
131
153
|
|
|
132
154
|
```sh
|
|
133
|
-
|
|
155
|
+
npx ablo login
|
|
156
|
+
npx ablo dev
|
|
134
157
|
```
|
|
135
158
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
159
|
+
The stored `mk_` project credential is used only to ensure the Git-derived child and
|
|
160
|
+
mint an expiring branch credential. `dev` writes that temporary key to
|
|
161
|
+
gitignored `.env.local`, pushes `ablo/schema.ts` to the child, and re-pushes on
|
|
162
|
+
every save. See [Branch-first development](./branch-development.md).
|
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
# Branch-first development
|
|
2
|
+
|
|
3
|
+
> Understand exactly what `ablo dev` prepares, what it watches, and how each Git branch gets an isolated Ablo schema and credential.
|
|
4
|
+
|
|
5
|
+
`ablo dev` is Ablo's schema-development loop. It prepares an isolated Ablo
|
|
6
|
+
branch for the Git branch you are working on, gives your local application a
|
|
7
|
+
short-lived credential for that branch, pushes the schema, and keeps the schema
|
|
8
|
+
registered as you edit it.
|
|
9
|
+
|
|
10
|
+
It does **not** start your application or run database migrations.
|
|
11
|
+
|
|
12
|
+
The everyday setup is two terminals:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# Terminal 1: your application
|
|
16
|
+
npm run dev
|
|
17
|
+
|
|
18
|
+
# Terminal 2: Ablo's schema loop
|
|
19
|
+
npx ablo dev
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## The mental model
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
Git branch
|
|
26
|
+
│
|
|
27
|
+
│ npx ablo dev
|
|
28
|
+
▼
|
|
29
|
+
Ablo branch
|
|
30
|
+
├── active schema artifact
|
|
31
|
+
├── isolated transaction plane
|
|
32
|
+
├── immutable branch id
|
|
33
|
+
└── expiring sk_test_ credential
|
|
34
|
+
│
|
|
35
|
+
▼
|
|
36
|
+
gitignored .env.local
|
|
37
|
+
│
|
|
38
|
+
▼
|
|
39
|
+
your local application
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
A branch name is a human handle. The credential carries the immutable Ablo
|
|
43
|
+
branch id, so application requests cannot switch branches by changing a slug or
|
|
44
|
+
request parameter.
|
|
45
|
+
|
|
46
|
+
Production is the root branch. Development branches are children; they do not
|
|
47
|
+
inherit production write authority.
|
|
48
|
+
|
|
49
|
+
## Before the first run
|
|
50
|
+
|
|
51
|
+
Initialize the project and sign in:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npx ablo init
|
|
55
|
+
npx ablo login
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Login stores one project-scoped `mk_` management credential. It has no
|
|
59
|
+
production/test mode and no application-data authority. It can manage projects
|
|
60
|
+
and branches and exchange for an expiring credential bound to one branch.
|
|
61
|
+
|
|
62
|
+
If you switch projects, log in for the selected project before running `dev`:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx ablo projects use orders
|
|
66
|
+
npx ablo login --project orders
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## What happens when you run it
|
|
70
|
+
|
|
71
|
+
Given:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
git switch -c feature/order-approval
|
|
75
|
+
npx ablo dev
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Ablo performs these steps.
|
|
79
|
+
|
|
80
|
+
### 1. Discover the branch
|
|
81
|
+
|
|
82
|
+
The first available source wins:
|
|
83
|
+
|
|
84
|
+
1. `--branch <name>`
|
|
85
|
+
2. `ABLO_BRANCH`
|
|
86
|
+
3. GitHub's `GITHUB_HEAD_REF` or `GITHUB_REF_NAME`
|
|
87
|
+
4. Vercel's `VERCEL_GIT_COMMIT_REF`
|
|
88
|
+
5. GitLab's `CI_COMMIT_REF_NAME`
|
|
89
|
+
6. the current local Git branch
|
|
90
|
+
|
|
91
|
+
The reference is normalized into a lowercase plane-safe slug:
|
|
92
|
+
|
|
93
|
+
```text
|
|
94
|
+
feature/order-approval → feature-order-approval
|
|
95
|
+
Feature: Billing V2 → feature-billing-v2
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Long names are shortened with a stable hash, so the same Git branch resolves to
|
|
99
|
+
the same Ablo branch on every machine.
|
|
100
|
+
|
|
101
|
+
### 2. Ensure the Ablo branch
|
|
102
|
+
|
|
103
|
+
The CLI lists branches for the active project and reuses one with the same slug.
|
|
104
|
+
If none exists, it creates a child of the project's production root.
|
|
105
|
+
|
|
106
|
+
Creation is idempotent: two CI jobs racing to ensure the same branch converge on
|
|
107
|
+
the same server record.
|
|
108
|
+
|
|
109
|
+
At creation, the child receives its own copy of the parent's active schema.
|
|
110
|
+
Later production schema pushes do not silently change an in-flight feature
|
|
111
|
+
branch.
|
|
112
|
+
|
|
113
|
+
### 3. Exchange for a temporary credential
|
|
114
|
+
|
|
115
|
+
The stored `mk_` credential authorizes the branch-management call. The server then
|
|
116
|
+
returns a new `sk_test_` credential bound only to the child branch.
|
|
117
|
+
|
|
118
|
+
The default lifetime is eight hours:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
npx ablo dev --branch-ttl-hours 12
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Allowed values are 1–168 hours. Rerunning `ablo dev` mints a fresh credential.
|
|
125
|
+
This lifetime belongs to the credential, not the branch. The branch persists
|
|
126
|
+
until `ablo branch delete` or preview automation removes it.
|
|
127
|
+
|
|
128
|
+
Temporary branch credentials can read, write, and push schema on their own
|
|
129
|
+
branch. They cannot create or delete siblings, mint sibling credentials, or
|
|
130
|
+
obtain production authority.
|
|
131
|
+
|
|
132
|
+
### 4. Wire the local application
|
|
133
|
+
|
|
134
|
+
The temporary credential is written to:
|
|
135
|
+
|
|
136
|
+
```dotenv
|
|
137
|
+
# .env.local
|
|
138
|
+
ABLO_API_KEY=sk_test_...
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The CLI creates `.env.local` with owner-only permissions when possible and adds
|
|
142
|
+
it to `.gitignore` if it is not already ignored. The key is not added to Ablo's
|
|
143
|
+
long-lived credential store.
|
|
144
|
+
|
|
145
|
+
Most application frameworks load `.env.local` automatically. Plain Node can
|
|
146
|
+
load it explicitly:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
node --env-file=.env.local app.ts
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
An `ABLO_API_KEY` exported in your shell overrides `.env.local` for child
|
|
153
|
+
processes. `ablo dev` warns when it detects that mismatch. Unset the exported
|
|
154
|
+
value before starting the application:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
unset ABLO_API_KEY
|
|
158
|
+
npm run dev
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### 5. Load and push the schema
|
|
162
|
+
|
|
163
|
+
By default, the CLI imports:
|
|
164
|
+
|
|
165
|
+
```text
|
|
166
|
+
ablo/schema.ts
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
and reads its `schema` export. Override either:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
npx ablo dev \
|
|
173
|
+
--schema src/ablo-schema.ts \
|
|
174
|
+
--export appSchema
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
The schema is serialized and uploaded to the selected branch. The server
|
|
178
|
+
compares it with that branch's active artifact and returns either:
|
|
179
|
+
|
|
180
|
+
- unchanged, with the current version;
|
|
181
|
+
- activated, with a new version and hash; or
|
|
182
|
+
- rejected, with the incompatible changes and the required next action.
|
|
183
|
+
|
|
184
|
+
`push` registers a contract. It does not execute DDL.
|
|
185
|
+
|
|
186
|
+
### 6. Watch for edits
|
|
187
|
+
|
|
188
|
+
After the first successful push, `ablo dev` watches the schema module. Editor
|
|
189
|
+
write/rename bursts are debounced into one reload and one push.
|
|
190
|
+
|
|
191
|
+
Stop it with `Ctrl-C`.
|
|
192
|
+
|
|
193
|
+
For a single branch preparation and push:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
npx ablo dev --no-watch
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Command reference
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
# Discover from Git and watch
|
|
203
|
+
npx ablo dev
|
|
204
|
+
|
|
205
|
+
# Choose the branch explicitly
|
|
206
|
+
npx ablo dev --branch preview-pr-482
|
|
207
|
+
|
|
208
|
+
# Push once
|
|
209
|
+
npx ablo dev --no-watch
|
|
210
|
+
|
|
211
|
+
# Change the temporary-key lifetime
|
|
212
|
+
npx ablo dev --branch-ttl-hours 24
|
|
213
|
+
|
|
214
|
+
# Use another schema module/export
|
|
215
|
+
npx ablo dev --schema db/ablo.ts --export schema
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Lower-level branch operations are also available:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
npx ablo branch list
|
|
223
|
+
npx ablo branch status feature-orders
|
|
224
|
+
npx ablo branch check feature-orders
|
|
225
|
+
npx ablo branch create feature-orders
|
|
226
|
+
npx ablo branch ensure preview-pr-482 --credential --ttl-hours 168 --json
|
|
227
|
+
npx ablo branch credential br_... --ttl-hours 8
|
|
228
|
+
npx ablo branch delete br_...
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Automation should retain immutable ids returned by the API. Slugs are for
|
|
232
|
+
people and discovery.
|
|
233
|
+
|
|
234
|
+
`branch status` and `branch check` are aliases. They show lifecycle state, the
|
|
235
|
+
active schema and hash, compatibility with the parent schema, the bound
|
|
236
|
+
database's safe coordinates, and an exact readiness fix.
|
|
237
|
+
|
|
238
|
+
## CI and preview deployments
|
|
239
|
+
|
|
240
|
+
For a one-shot CI schema check:
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
# Store the project management credential as the masked secret.
|
|
244
|
+
ABLO_MANAGEMENT_KEY="mk_..." \
|
|
245
|
+
ABLO_BRANCH="preview-pr-${PR_NUMBER}" \
|
|
246
|
+
npx ablo dev --no-watch
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
For infrastructure that needs the credential response directly:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
npx ablo branch ensure "preview-pr-${PR_NUMBER}" \
|
|
253
|
+
--kind preview \
|
|
254
|
+
--credential \
|
|
255
|
+
--ttl-hours 168 \
|
|
256
|
+
--json
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
`--credential` explicitly requests plaintext secret material. Treat the JSON
|
|
260
|
+
result as a secret, mask it in logs, and pass it through the deployment
|
|
261
|
+
provider's secret-variable mechanism.
|
|
262
|
+
|
|
263
|
+
Closing a preview should call `branch delete`. Deletion immediately makes
|
|
264
|
+
branch-bound credentials fail authentication even if their expiry is later.
|
|
265
|
+
|
|
266
|
+
## Managing branches in Sync Web
|
|
267
|
+
|
|
268
|
+
The persistent dashboard header selects a project and then one branch inside it. The
|
|
269
|
+
selection scopes API keys, Schema, Audit log, and Server log. Production is the
|
|
270
|
+
protected root; every other item is a named development branch.
|
|
271
|
+
|
|
272
|
+
Use the **Branches** page to create, select, inspect, or delete a branch.
|
|
273
|
+
Deleting a child revokes all of its credentials first, removes its datasource
|
|
274
|
+
connection material, and then removes it from discovery. It never deletes a
|
|
275
|
+
sibling, the production root, customer tables, or retained schema history.
|
|
276
|
+
|
|
277
|
+
See [Ablo branch lifecycle](../../../docs/explainers/branch-lifecycle.md) for
|
|
278
|
+
the complete project/branch mental model and dashboard journey.
|
|
279
|
+
|
|
280
|
+
## Your database and migrations
|
|
281
|
+
|
|
282
|
+
There are two independent contracts:
|
|
283
|
+
|
|
284
|
+
```text
|
|
285
|
+
Your ORM/migration tool owns tables, columns, relations, and DDL
|
|
286
|
+
Ablo schema owns the coordination contract for synced models
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
`ablo dev` currently isolates the Ablo branch and schema. It does not:
|
|
290
|
+
|
|
291
|
+
- run Prisma, Drizzle, or SQL migrations;
|
|
292
|
+
- create a Neon/Supabase/RDS database branch;
|
|
293
|
+
- copy production data;
|
|
294
|
+
- automatically register whichever `DATABASE_URL` happens to be present.
|
|
295
|
+
|
|
296
|
+
The last point is a safety boundary. A generic `DATABASE_URL` does not prove
|
|
297
|
+
that the database is an isolated feature branch; automatically registering it
|
|
298
|
+
could bind a development credential to production.
|
|
299
|
+
|
|
300
|
+
Until provider-verified database-branch binding lands, use Ablo's hosted branch
|
|
301
|
+
plane for the inner loop or explicitly prepare and review an isolated database
|
|
302
|
+
through [Connect Your Database](./data-sources.md). Never point a child branch at
|
|
303
|
+
production merely because its migrations are compatible.
|
|
304
|
+
|
|
305
|
+
## Production rollout
|
|
306
|
+
|
|
307
|
+
There is intentionally no `branch merge` that promotes child rows or logs.
|
|
308
|
+
|
|
309
|
+
Production rollout remains:
|
|
310
|
+
|
|
311
|
+
1. Merge code and migration files through Git.
|
|
312
|
+
2. Run the reviewed migration against the production database.
|
|
313
|
+
3. Push the production/root Ablo schema through the deployment workflow.
|
|
314
|
+
4. Deploy the application.
|
|
315
|
+
|
|
316
|
+
The feature branch proves the change. It does not become production.
|
|
317
|
+
|
|
318
|
+
## Troubleshooting
|
|
319
|
+
|
|
320
|
+
### “Creating a development branch needs the active project CLI key”
|
|
321
|
+
|
|
322
|
+
Run:
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
npx ablo login
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
For a non-default project:
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
npx ablo login --project <project>
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
If `ABLO_API_KEY` is exported, it overrides the stored login key. Unset it when
|
|
335
|
+
you want the CLI to use the active project's stored profile.
|
|
336
|
+
|
|
337
|
+
### “Branch credentials cannot manage branches”
|
|
338
|
+
|
|
339
|
+
You supplied a temporary child credential to a management command. Branch
|
|
340
|
+
runtime credentials are deliberately leaf authority. Unset the override and let
|
|
341
|
+
the CLI use the project login key.
|
|
342
|
+
|
|
343
|
+
### Check the whole branch
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
npx ablo branch check feature-order-approval
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
The result distinguishes a missing schema, a branch lifecycle failure, and an
|
|
350
|
+
unready connected database. A hosted branch is a valid development state and
|
|
351
|
+
is reported explicitly rather than as a missing database.
|
|
352
|
+
|
|
353
|
+
### The app still reaches another plane
|
|
354
|
+
|
|
355
|
+
Check for an exported variable:
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
env | grep '^ABLO_API_KEY='
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
An exported value wins over `.env.local`. Unset it and restart the application
|
|
362
|
+
process so the framework reloads `.env.local`.
|
|
363
|
+
|
|
364
|
+
### `server_execute_unknown_model`
|
|
365
|
+
|
|
366
|
+
The active branch does not have the schema containing that model. Keep
|
|
367
|
+
`ablo dev` running, or push once:
|
|
368
|
+
|
|
369
|
+
```bash
|
|
370
|
+
npx ablo dev --no-watch
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
Confirm that `--schema` and `--export` point at the module your application
|
|
374
|
+
uses.
|
|
375
|
+
|
|
376
|
+
### Git branch discovery fails
|
|
377
|
+
|
|
378
|
+
Detached checkouts may not expose a local branch. Pass the intended name:
|
|
379
|
+
|
|
380
|
+
```bash
|
|
381
|
+
npx ablo dev --branch preview-pr-482
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
or set `ABLO_BRANCH` in CI.
|
|
385
|
+
|
|
386
|
+
## Related guides
|
|
387
|
+
|
|
388
|
+
- [Quickstart](./quickstart.md) — install, connect, define a schema, and write.
|
|
389
|
+
- [CLI](./cli.md) — the complete command surface.
|
|
390
|
+
- [Schema Contract](./schema-contract.md) — what the registered schema controls.
|
|
391
|
+
- [Connect Your Database](./data-sources.md) — Postgres roles, WAL, and database ownership.
|
|
392
|
+
- [Deployment](./deployment.md) — production schema rollout.
|