@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/cli.md
CHANGED
|
@@ -11,7 +11,7 @@ SQL — so what you test is what ships.
|
|
|
11
11
|
```bash
|
|
12
12
|
npx ablo init # scaffold ablo/schema.ts + client
|
|
13
13
|
npx ablo login # authorize in the browser
|
|
14
|
-
npx ablo dev #
|
|
14
|
+
npx ablo dev # prepare an isolated Git branch + push/watch
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
**Two setup styles, and they pick your commands.** If your app database is the
|
|
@@ -19,42 +19,43 @@ source of truth, expose a [Data Source endpoint](./data-sources.md) and keep DB
|
|
|
19
19
|
credentials in your app. If you explicitly want Ablo to open a Postgres
|
|
20
20
|
connection, use the **Direct Postgres connector** commands: `ablo migrate`
|
|
21
21
|
applies changes to your own `DATABASE_URL`, and `ablo check` / `ablo pull`
|
|
22
|
-
adopt tables you already have. Hosted
|
|
22
|
+
adopt tables you already have. Hosted branch commands are tagged **Hosted**;
|
|
23
23
|
direct-connector commands are tagged **Direct Postgres**.
|
|
24
24
|
|
|
25
25
|
## Authenticate
|
|
26
26
|
|
|
27
27
|
`ablo login` runs the OAuth 2.0 device flow: it opens your browser, you choose
|
|
28
28
|
**log in** or **create an account** and approve, and the CLI provisions a
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
This mirrors `stripe login`.
|
|
29
|
+
90-day, project-scoped `mk_` management credential. It has no test/live mode
|
|
30
|
+
and cannot read or write application data. `ablo dev` uses it to create or
|
|
31
|
+
resume a branch and exchanges it for a temporary branch-bound runtime key.
|
|
33
32
|
|
|
34
33
|
| Command | What it does |
|
|
35
34
|
| ------------------------ | -------------------------------------------------------------------------- |
|
|
36
|
-
| `ablo login` | Authorize in the browser;
|
|
37
|
-
| `ablo login --project <slug>` | Same,
|
|
38
|
-
| `ablo logout` | Remove the stored
|
|
39
|
-
| `ablo status` | Show the active org,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
schema
|
|
56
|
-
|
|
57
|
-
|
|
35
|
+
| `ablo login` | Authorize in the browser; store one project management credential. |
|
|
36
|
+
| `ablo login --project <slug>` | Same, scoped to a project, which becomes active. |
|
|
37
|
+
| `ablo logout` | Remove the stored credentials. |
|
|
38
|
+
| `ablo status` | Show the active org/project, effective credential, branch target, and server health. |
|
|
39
|
+
|
|
40
|
+
Keys live in `~/.config/ablo/credentials.json` (mode `0600`), keyed by project.
|
|
41
|
+
The non-secret `config.json` holds the active project. In **CI**, don't log in —
|
|
42
|
+
set the project management credential as `ABLO_MANAGEMENT_KEY`; it overrides the
|
|
43
|
+
stored credential during branch bootstrap.
|
|
44
|
+
|
|
45
|
+
## Development branches vs live
|
|
46
|
+
|
|
47
|
+
A branch is your project at full strength over its own rows: the same models,
|
|
48
|
+
the same schema artifacts, the same claims and the same rules production runs.
|
|
49
|
+
|
|
50
|
+
Production is the project root. `ablo dev` creates or reuses a child branch for
|
|
51
|
+
your Git branch, then mints a temporary `sk_test_` key bound to that child.
|
|
52
|
+
Reads, writes, schema artifacts, claims, and credentials stay isolated from
|
|
53
|
+
production and from other development branches, which is what makes a
|
|
54
|
+
schema-changing pull request as routine as a code-only one.
|
|
55
|
+
|
|
56
|
+
There is no local mode switch. Development selection comes from Git or
|
|
57
|
+
`--branch`; production authority comes only from an explicit live credential.
|
|
58
|
+
Production schema changes use the reviewed one-shot path in
|
|
58
59
|
[Deployment](./deployment.md).
|
|
59
60
|
|
|
60
61
|
## Projects
|
|
@@ -70,7 +71,7 @@ selects which profile every command authenticates with.
|
|
|
70
71
|
| `ablo projects list` | List the org's projects (marks the active one and the org-default). |
|
|
71
72
|
| `ablo projects create <slug>` | Create a project (`--name "Display Name"`). Its keys/schema/data are isolated. |
|
|
72
73
|
| `ablo projects use <slug>` | Switch the active project. `ablo projects use default` returns to the org-default. |
|
|
73
|
-
| `ablo login --project <slug>` |
|
|
74
|
+
| `ablo login --project <slug>` | Store management access for a project and make it active. |
|
|
74
75
|
|
|
75
76
|
Because keys are fixed to a project, `projects use` only changes which profile
|
|
76
77
|
is active — it never re-scopes an existing key. Switch to a project you haven't
|
|
@@ -81,14 +82,15 @@ npx ablo projects use war-room
|
|
|
81
82
|
# ✓ now targeting project war-room (prj_…)
|
|
82
83
|
# No key stored for this project yet — run `ablo login --project war-room` to mint one.
|
|
83
84
|
|
|
84
|
-
npx ablo login --project war-room #
|
|
85
|
+
npx ablo login --project war-room # stores its management credential, keeps it active
|
|
85
86
|
```
|
|
86
87
|
|
|
87
88
|
If you run a project-scoped command (`push`, `dev`) while the active project has
|
|
88
89
|
no key — but other projects do — the CLI **refuses** rather than silently
|
|
89
90
|
deploying with the wrong project's credential, and names the fix
|
|
90
|
-
(`ablo login --project <slug>`). In CI, an explicit `
|
|
91
|
-
profiles
|
|
91
|
+
(`ablo login --project <slug>`). In CI, an explicit `ABLO_MANAGEMENT_KEY`
|
|
92
|
+
bypasses profiles for project/branch administration; the runtime key remains
|
|
93
|
+
`ABLO_API_KEY`.
|
|
92
94
|
|
|
93
95
|
## Commands
|
|
94
96
|
|
|
@@ -96,10 +98,10 @@ profiles entirely: it acts in whatever project it was minted for.
|
|
|
96
98
|
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
|
|
97
99
|
| `ablo init` | Scaffold `ablo/` (`schema.ts`, client, optional Data Source / agent / component), write `.env`, install the SDK. Offers to log in at the end. |: |
|
|
98
100
|
| `ablo login` / `logout` / `status` | Authentication & status (above). |: |
|
|
99
|
-
| `ablo mode [sandbox\|production]` | Switch active environment. |: |
|
|
100
101
|
| `ablo projects list\|create\|use\|rename` | Manage projects and the active one (see [Projects](#projects)). Each project's keys/schema/data are isolated. | `--name "<display>"` (create/rename) |
|
|
101
|
-
| `ablo dev` | **Hosted**:
|
|
102
|
-
| `ablo
|
|
102
|
+
| `ablo dev` | **Hosted**: ensure an isolated Git branch, wire its temporary key, push, then watch `ablo/schema.ts`. | `--branch <slug>`, `--branch-ttl-hours <1-168>`, `--no-watch`, `--schema`, `--export`, `--url` |
|
|
103
|
+
| `ablo branch list\|status\|check\|create\|ensure\|credential\|delete` | Manage and diagnose immutable branch planes and expiring credentials. | Run `ablo branch --help`; use `--json` for automation. |
|
|
104
|
+
| `ablo logs` | Tail the effective credential's branch activity. Follows by default. | `-n, --tail <N>`, `--since <dur\|ts>`, `--model`, `--op`, `--json`, `--no-follow` |
|
|
103
105
|
| `ablo push` | **Hosted**: upload the schema to Ablo; the server diffs, migrates, and activates it. | `--force`, `--rename old:new`, `--backfill model.field=value`, `--schema`, `--export`, `--url` |
|
|
104
106
|
| `ablo migrate` | **Direct Postgres**: provision just the synced models (plus the adapter's `ablo_outbox` / `ablo_idempotency`) in your own `DATABASE_URL`. Leaves your other tables alone. | `--dry-run`, `--output <file>`, `--schema`, `--export` |
|
|
105
107
|
| `ablo pull` | **Direct Postgres**: generate `defineSchema(...)` from your existing tables (read-only, like `prisma db pull`). | `--out <path>`, `--app-schema <name>`, `--import <pkg>`, `--force` |
|
|
@@ -131,16 +133,22 @@ HTTP at `/api/docs/<slug>` and through the docs MCP server.
|
|
|
131
133
|
|
|
132
134
|
## `ablo dev`
|
|
133
135
|
|
|
134
|
-
The development loop. It
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
136
|
+
The branch-first development loop. It discovers your Git/CI branch, ensures the
|
|
137
|
+
matching Ablo child branch, exchanges the stored `mk_` project credential for an
|
|
138
|
+
expiring branch-only key, writes that key to gitignored `.env.local`, pushes
|
|
139
|
+
`ablo/schema.ts`, and re-pushes on every save.
|
|
138
140
|
|
|
139
141
|
```bash
|
|
140
|
-
npx ablo dev
|
|
141
|
-
npx ablo dev --
|
|
142
|
+
npx ablo dev # discover from Git, push + watch
|
|
143
|
+
npx ablo dev --branch preview-pr-482 # explicit branch
|
|
144
|
+
npx ablo dev --no-watch # prepare, push once, exit
|
|
145
|
+
npx ablo dev --branch-ttl-hours 24 # change temporary-key lifetime
|
|
142
146
|
```
|
|
143
147
|
|
|
148
|
+
It does not start your app, run migrations, create a database-provider branch,
|
|
149
|
+
or copy production rows. Read [Branch-first development](./branch-development.md)
|
|
150
|
+
for the exact discovery order, CI flow, database boundary, and troubleshooting.
|
|
151
|
+
|
|
144
152
|
## `ablo logs`
|
|
145
153
|
|
|
146
154
|
Tail commit activity, like `stripe logs tail`. Scope comes from the key — a test
|
|
@@ -212,7 +220,7 @@ reshaping it. `ablo check` is read-only; it never proposes a migration.
|
|
|
212
220
|
|
|
213
221
|
Same engine, two setups. If you use the **Direct Postgres connector**, use
|
|
214
222
|
`ablo migrate` — it provisions the synced models in your own `DATABASE_URL`. If
|
|
215
|
-
Ablo manages the
|
|
223
|
+
Ablo manages the hosted store, use `ablo push` and `ablo dev` — the
|
|
216
224
|
server applies the change and version-gates connecting clients.
|
|
217
225
|
|
|
218
226
|
```bash
|
package/docs/data-sources.md
CHANGED
|
@@ -244,6 +244,17 @@ lifecycle. It needs no replication setup, which is exactly why it's the fallback
|
|
|
244
244
|
reach for it only when logical replication isn't available, and prefer `ablo
|
|
245
245
|
connect` everywhere else.
|
|
246
246
|
|
|
247
|
+
The current Prisma, Drizzle, and Kysely adapters are PostgreSQL bindings. Their
|
|
248
|
+
profiles record three independent facts: the database is PostgreSQL, the binding
|
|
249
|
+
is Prisma/Drizzle/Kysely, and observation is either the transactional outbox or
|
|
250
|
+
PostgreSQL WAL. An ORM name does not imply that the same adapter supports every
|
|
251
|
+
database that ORM can connect to.
|
|
252
|
+
|
|
253
|
+
The outbox automatically observes writes made through Ablo. A write made
|
|
254
|
+
directly by other application code is visible only if that code writes the same
|
|
255
|
+
outbox record in its transaction. Native WAL observation sees both Ablo and
|
|
256
|
+
external writes.
|
|
257
|
+
|
|
247
258
|
## Next steps
|
|
248
259
|
|
|
249
260
|
- [Quickstart](./quickstart.md) — connect and write through `ablo.<model>`.
|
package/docs/deployment.md
CHANGED
|
@@ -54,25 +54,25 @@ Everything below is those three in order.
|
|
|
54
54
|
### Planes: what a deployment targets
|
|
55
55
|
|
|
56
56
|
A **plane** is the isolation unit a credential acts on. `production` is the root
|
|
57
|
-
|
|
58
|
-
which three is most of what production readiness means:
|
|
57
|
+
branch; development and preview branches are children. Three things are
|
|
58
|
+
per-plane, and knowing which three is most of what production readiness means:
|
|
59
59
|
|
|
60
|
-
- **Rows:** a
|
|
60
|
+
- **Rows:** a child-branch write is invisible to production and every sibling.
|
|
61
61
|
- **The registered database:** one per plane, so your production database and
|
|
62
62
|
your dev database are separate registrations.
|
|
63
63
|
- **The active schema artifact:** the model shapes the engine actually routes on.
|
|
64
64
|
|
|
65
|
-
A key's plane is fixed at mint
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
passes
|
|
65
|
+
A key's plane is fixed at mint: `sk_live_` acts on production, while `sk_test_`
|
|
66
|
+
is bound to one development branch. The immutable branch id,
|
|
67
|
+
not a user-supplied slug, is the selector. This is why application code never
|
|
68
|
+
passes an environment.
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
70
|
+
A child copies its parent's active schema when it is created, then owns its
|
|
71
|
+
schema history. A child push never changes production. Production gets new
|
|
72
|
+
models only when the reviewed deployment pushes them to the root.
|
|
73
|
+
|
|
74
|
+
There is no shared development plane. New credentials are branch-bound; follow
|
|
75
|
+
[Branch-first development](./branch-development.md).
|
|
76
76
|
|
|
77
77
|
## 1. The database production writes to
|
|
78
78
|
|
|
@@ -141,9 +141,10 @@ minting. Two things bite specifically at deploy time.
|
|
|
141
141
|
observe-only `rk_live_` by design, so a stolen CLI config cannot write to
|
|
142
142
|
production. A production deploy needs a **secret** `sk_live_` from the dashboard,
|
|
143
143
|
supplied as `ABLO_API_KEY`. You do not have to discover this from a failed
|
|
144
|
-
deploy: `ablo login
|
|
145
|
-
|
|
146
|
-
|
|
144
|
+
deploy: `ablo login` and `ablo status` name what the key in hand does, and
|
|
145
|
+
`ablo status --json` reports it as `effectiveKey.kind` for a pipeline to check
|
|
146
|
+
before it pushes. The deploy itself uses an explicit dashboard `sk_live_` in
|
|
147
|
+
`ABLO_API_KEY`; there is no local mode switch.
|
|
147
148
|
|
|
148
149
|
**An explicit key always wins.** The CLI resolves `ABLO_API_KEY`, then
|
|
149
150
|
`.env.local`, then `.env`, then the stored login — and `ablo status` prints which
|
|
@@ -204,9 +205,9 @@ answer to where a push would land.
|
|
|
204
205
|
|
|
205
206
|
## Webhooks point at the deployed URL
|
|
206
207
|
|
|
207
|
-
`npx ablo dev`
|
|
208
|
-
|
|
209
|
-
|
|
208
|
+
`npx ablo dev` prepares the schema branch; it does not forward webhooks. A
|
|
209
|
+
deployed HTTPS endpoint is registered once, and Ablo returns the signing secret
|
|
210
|
+
a single time:
|
|
210
211
|
|
|
211
212
|
```bash
|
|
212
213
|
ABLO_API_KEY=sk_live_… npx ablo webhooks create https://yourapp.com/api/ablo/[...all]
|
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
# AI SDK
|
|
1
|
+
# AI SDK Tools
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Give an AI SDK agent safe access to the same typed Ablo resources as your
|
|
4
|
+
> backend.
|
|
4
5
|
|
|
5
6
|
Use AI SDK for the agent loop and Ablo for the state boundary inside the tool.
|
|
6
7
|
When an agent updates a shared record from inside a tool call you have a
|
|
7
|
-
concurrency problem: another agent may be editing the same row, and
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
Claims don't lock. If another writer holds the row, `claim` waits for them,
|
|
13
|
-
re-reads the fresh row, then hands it to you — so two writers serialize instead
|
|
14
|
-
of clobbering.
|
|
8
|
+
concurrency problem: another agent or a person may be editing the same row, and
|
|
9
|
+
a naive write can overwrite work the model never saw. Ablo's tool adapters put
|
|
10
|
+
the authoritative read, retry, claim, and confirmed-write behavior behind the
|
|
11
|
+
ordinary AI SDK tool contract.
|
|
15
12
|
|
|
16
13
|
```ts
|
|
17
14
|
// app/api/chat/route.ts
|
|
@@ -20,11 +17,11 @@ import { defineSchema, model, z as schemaZ } from '@abloatai/ablo/schema';
|
|
|
20
17
|
import { anthropic } from '@ai-sdk/anthropic';
|
|
21
18
|
import {
|
|
22
19
|
streamText,
|
|
23
|
-
tool,
|
|
24
20
|
convertToModelMessages,
|
|
25
21
|
stepCountIs,
|
|
26
22
|
type UIMessage,
|
|
27
23
|
} from 'ai';
|
|
24
|
+
import { updateTool } from '@abloatai/ablo/ai-sdk';
|
|
28
25
|
import { z } from 'zod';
|
|
29
26
|
|
|
30
27
|
export const runtime = 'nodejs';
|
|
@@ -43,42 +40,19 @@ const ablo = Ablo({
|
|
|
43
40
|
transport: 'http',
|
|
44
41
|
});
|
|
45
42
|
|
|
46
|
-
const updateTask =
|
|
47
|
-
|
|
43
|
+
const updateTask = updateTool(ablo.tasks, {
|
|
44
|
+
title: 'Update task',
|
|
45
|
+
description: 'Update a task without overwriting concurrent work.',
|
|
48
46
|
inputSchema: z.object({
|
|
49
47
|
taskId: z.string(),
|
|
50
48
|
status: z.enum(['todo', 'doing', 'done']).optional(),
|
|
51
49
|
summary: z.string().optional(),
|
|
52
50
|
}),
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (!task) return { ok: false, reason: 'not_found' };
|
|
59
|
-
|
|
60
|
-
// If another agent already holds this row, claim waits for them to finish,
|
|
61
|
-
// re-reads the fresh row, then hands it back on `claim.data`. The claim is
|
|
62
|
-
// released automatically when it goes out of scope.
|
|
63
|
-
await using claim = await ablo.tasks.claim({
|
|
64
|
-
id: taskId,
|
|
65
|
-
description: 'editing',
|
|
66
|
-
ttl: '2m',
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
// Because you hold the claim, this update is rejected if the row changed
|
|
70
|
-
// underneath you, instead of silently overwriting it.
|
|
71
|
-
const updated = await ablo.tasks.update({
|
|
72
|
-
id: claim.data.id,
|
|
73
|
-
data: {
|
|
74
|
-
status: status ?? claim.data.status,
|
|
75
|
-
summary: summary ?? claim.data.summary,
|
|
76
|
-
},
|
|
77
|
-
wait: 'confirmed',
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
return { ok: true, task: updated };
|
|
81
|
-
},
|
|
51
|
+
id: ({ taskId }) => taskId,
|
|
52
|
+
apply: (current, { status, summary }) => ({
|
|
53
|
+
status: status ?? current.status,
|
|
54
|
+
summary: summary ?? current.summary,
|
|
55
|
+
}),
|
|
82
56
|
});
|
|
83
57
|
|
|
84
58
|
export async function POST(req: Request) {
|
|
@@ -100,13 +74,12 @@ export async function POST(req: Request) {
|
|
|
100
74
|
|
|
101
75
|
The model provider is interchangeable — swap `anthropic(...)` for any
|
|
102
76
|
server-bound provider instance. What matters is that the route binds the model on
|
|
103
|
-
the server (never trusting one sent in the request body)
|
|
104
|
-
`UIMessage[]` with `convertToModelMessages
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
- and auto-releases the claim when the tool returns.
|
|
77
|
+
the server (never trusting one sent in the request body) and converts the
|
|
78
|
+
incoming `UIMessage[]` with `convertToModelMessages`.
|
|
79
|
+
|
|
80
|
+
`updateTool` defaults to a functional update: Ablo re-reads and reapplies the
|
|
81
|
+
patch if another participant writes first. Use `strategy: 'claim'` when the
|
|
82
|
+
model should skip work already owned by someone else, or `strategy: 'queue'`
|
|
83
|
+
when it should wait in Ablo's server-owned FIFO claim queue. The same entrypoint
|
|
84
|
+
also exports `readTool`, `createTool`, and `deleteTool`; deletes require AI SDK
|
|
85
|
+
approval unless the application explicitly disables it.
|
package/docs/how-it-works.md
CHANGED
|
@@ -69,8 +69,9 @@ database differs by environment — the code is identical.
|
|
|
69
69
|
- **Production:** your Postgres. `ablo connect` sets up a scoped writer role and
|
|
70
70
|
logical replication; your rows live in your database, and Ablo writes to them
|
|
71
71
|
through that role.
|
|
72
|
-
- **
|
|
73
|
-
models, same code, a different
|
|
72
|
+
- **Development branches and local dev:** a separate or local Postgres, or a
|
|
73
|
+
branch of the one you already run. Same models, same code, a different
|
|
74
|
+
database behind them.
|
|
74
75
|
- **Before you connect one.** Ablo keeps state in its own log, so you can build the
|
|
75
76
|
whole app today and point it at a real database when you're ready.
|
|
76
77
|
|
package/docs/index.md
CHANGED
|
@@ -60,11 +60,14 @@ based on a row that has since changed is turned away rather than applied.
|
|
|
60
60
|
stay in your own migrations.
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
|
-
npx ablo init
|
|
63
|
+
npx ablo init
|
|
64
|
+
npx ablo dev
|
|
64
65
|
```
|
|
65
66
|
|
|
66
|
-
`
|
|
67
|
-
|
|
67
|
+
`dev` gives the current Git branch an isolated Ablo branch, wires its temporary key,
|
|
68
|
+
pushes the schema, and watches for changes. Until the server has your schema, a write to
|
|
69
|
+
a new model fails with `server_execute_unknown_model`. See
|
|
70
|
+
[Branch-first development](./branch-development.md).
|
|
68
71
|
</Step>
|
|
69
72
|
|
|
70
73
|
<Step title="Connect the database the rows live in">
|
|
@@ -161,6 +164,7 @@ default caller, not a special one.
|
|
|
161
164
|
|
|
162
165
|
- [Quickstart](./quickstart.md) — make your first coordinated write.
|
|
163
166
|
- [Integration Guide](./integration-guide.md) — the canonical end-to-end integration.
|
|
167
|
+
- [Integrations](./integrations.md) — long-running tasks, ingestion, and other application-edge runtimes.
|
|
164
168
|
- [CLI & Migrations](./cli.md) — `init` / `connect` / `push` / `migrate` / `generate`.
|
|
165
169
|
- [Connect Your Database](./data-sources.md) — where rows land when your own database is canonical.
|
|
166
170
|
- [Deployment](./deployment.md) — the database, the keys, and the schema push that take an integration to production.
|
|
@@ -66,24 +66,17 @@ deterministic demo; it does not call your API key or mutate hosted Ablo data.
|
|
|
66
66
|
It is also built for coding agents: copy the sandbox prompt into Claude Code or
|
|
67
67
|
Codex and ask it to wire one real model through the schema model API.
|
|
68
68
|
|
|
69
|
-
Use
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
- it mints `sk_test_*` keys,
|
|
75
|
-
- it can be reset without touching live state,
|
|
76
|
-
- additional sandboxes can start blank or from copied live configuration.
|
|
77
|
-
|
|
78
|
-
Live keys and sandbox keys are separate. Use `sk_test_*` while wiring your app,
|
|
79
|
-
agents, and Data Source endpoint; move to `sk_live_*` only when the same schema
|
|
80
|
-
and write path are ready for production.
|
|
69
|
+
Use `npx ablo dev` for real integration work. It derives an immutable branch
|
|
70
|
+
from Git, inherits the parent schema, and writes a temporary branch credential
|
|
71
|
+
to `.env.local`. Each developer or pull request gets independent schema, rows,
|
|
72
|
+
claims, and logs. Use an explicit `sk_live_*` root credential only in the
|
|
73
|
+
reviewed production deployment.
|
|
81
74
|
|
|
82
75
|
When handing this to a coding agent, give it a concrete target:
|
|
83
76
|
|
|
84
77
|
```txt
|
|
85
78
|
Add Ablo to this app for one model your agents edit.
|
|
86
|
-
|
|
79
|
+
Run npx ablo dev and use its branch-bound key. Declare schema, add the Ablo client, replace
|
|
87
80
|
one write with ablo.<model>.update(..., { readAt, onStale: 'reject',
|
|
88
81
|
wait: 'confirmed' }), and add a smoke test for two concurrent writers.
|
|
89
82
|
```
|