@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/llms.txt CHANGED
@@ -23,9 +23,9 @@ The two MCP servers do different jobs and are the most common mix-up: to change
23
23
 
24
24
  First action when integrating into an app: run `npx ablo init --yes --framework <nextjs|vite|remix|vanilla>`. Agents have no TTY — `--yes` is REQUIRED or it HANGS. It scaffolds `ablo/schema.ts`, the `Ablo({ schema, apiKey })` client, and (for Next.js) the browser provider + session route. All on the current API. Edit the generated files rather than hand-writing from this doc. Connecting a database is a SEPARATE step with one path — logical replication via `npx ablo connect` (see Storage Boundary); the signed Data Source endpoint is the fallback when database credentials must stay inside the app.
25
25
 
26
- Second: make sure a key exists — WITHOUT printing it. The key is a secret; it must never appear in your output, your reasoning, or a file you echo (it would live in the conversation history forever). Check PRESENCE only: `[ -n "$ABLO_API_KEY" ] && echo set` and `grep -cq '^ABLO_API_KEY=' .env.local && echo wired` — never `cat .env.local`, never `echo $ABLO_API_KEY`. If neither check passes, ask the HUMAN to run `npx ablo login` once — it opens a browser and saves a `sk_test_` key locally; an agent must NOT run it. You never copy the key by hand: the next step writes it into `.env.local` (and gitignores it) for you.
26
+ Second: make sure a key exists — WITHOUT printing it. The key is a secret; it must never appear in your output, your reasoning, or a file you echo (it would live in the conversation history forever). Check PRESENCE only: `[ -n "$ABLO_API_KEY" ] && echo set` and `grep -cq '^ABLO_API_KEY=' .env.local && echo wired` — never `cat .env.local`, never `echo $ABLO_API_KEY`. If neither check passes, ask the HUMAN to run `npx ablo login` once — it opens a browser and saves a project-scoped branch-management key locally; an agent must NOT run it. You never copy a runtime key by hand: the next step mints one for the development branch, writes it into `.env.local`, and gitignores it.
27
27
 
28
- Then PUSH — this is the step everything depends on. The server keeps its OWN copy of the schema. Run `npx ablo push`: it pushes `ablo/schema.ts` (sandbox) AND writes `ABLO_API_KEY` into `.env.local` from the stored login. Until the schema is pushed, EVERY write to a new or changed model fails with `server_execute_unknown_model`. Re-run it after schema changes. `push` is one-shot; `dev` is the watcher, so use `npx ablo dev --no-watch` only when you intentionally want the dev command to push once and exit.
28
+ Then PREPARE THE BRANCH AND PUSH — this is the step everything depends on. The server keeps its OWN copy of the schema. Run `npx ablo dev --no-watch --branch <git-or-ci-ref>`: it ensures an isolated child branch, exchanges the CLI key for an expiring branch-only `sk_test_` key, writes that key to gitignored `.env.local`, pushes `ablo/schema.ts`, and exits. Until the schema is pushed, EVERY write to a new or changed model fails with `server_execute_unknown_model`. Re-run it after schema changes. Plain `dev` watches forever; never run it bare in an agent. `push` is the lower-level one-shot command for an already selected credential, including a reviewed production deployment.
29
29
 
30
30
  ## Projects (one org, many apps)
31
31
 
@@ -182,22 +182,23 @@ claims, stale-write rejection, receipts, and deltas, but it does not use a real
182
182
  API key. It also exposes a Claude Code / Codex handoff prompt. Prefer that shape
183
183
  when an agent is asked to "make Ablo work" in an existing app.
184
184
 
185
- Authenticated org sandboxes are real test environments. Treat the default
186
- sandbox like Stripe test mode: it has an isolated sync group prefix and mints
187
- `sk_test_*` keys. The sandbox CAN host rows in Ablo's test plane, so you can try
188
- Ablo with NO database — `apiKey` only, nothing else. (In production, your own
189
- Postgres is the system of record.) Extra sandboxes can start blank or copy live
190
- configuration. Resetting a sandbox creates a clean future stream without
191
- touching live data. Use `sk_live_*` only for production.
185
+ Authenticated development branches are real test environments. `ablo dev`
186
+ derives one from Git and mints an expiring `sk_test_*` key bound to its immutable
187
+ branch id. A branch CAN host rows in Ablo's test plane, so you can try Ablo with
188
+ NO database — `apiKey` only, nothing else. (In production, your own Postgres is
189
+ the system of record.) Branch schemas and rows are isolated from siblings and
190
+ production. There is no shared-sandbox escape hatch. Use `sk_live_*` only for
191
+ production.
192
192
 
193
- For coding agents, the sandbox success path is: pick one shared model,
194
- declare schema, create the Ablo client, replace one direct mutation with a typed
195
- `ablo.<model>.update(...)`, use selector `useAblo` for live reads, and add a
196
- two-writer stale/claim smoke test.
193
+ For coding agents, the development success path is: pick one shared model,
194
+ declare schema, prepare an explicit branch with
195
+ `ablo dev --no-watch --branch <git-or-ci-ref>`, create the Ablo client, replace
196
+ one direct mutation with a typed `ablo.<model>.update(...)`, use selector
197
+ `useAblo` for live reads, and add a two-writer stale/claim smoke test.
197
198
 
198
199
  ## Production
199
200
 
200
- A PLANE is what a credential acts on: `production` is the root, sandboxes sit beside it. Rows, the registered database, and the active schema artifact are all PER PLANE, and a key's plane is fixed at mint by its prefix (`sk_live_` → production, `sk_test_` → sandbox) — there is no runtime override, which is why app code never passes an environment. ONE ASYMMETRY: a sandbox with no schema artifact of its own READS PRODUCTION'S, so a production push reaches sandboxes; a SANDBOX push does NOT reach production — it creates a sandbox artifact that shadows production for that sandbox's readers only. Production gets models when you push to production.
201
+ A PLANE is what a credential acts on: `production` is the root branch and development/preview branches are children. Rows, the registered database, and the active schema artifact are all PER PLANE. A key's immutable branch binding is fixed at mint (`sk_live_` → production; `sk_test_` → one child), so app code never passes an environment. A child copies its parent's active schema at creation and owns its artifact after that. A CHILD push does NOT reach production. Production gets models only when the reviewed deployment pushes to the root.
201
202
 
202
203
  Going live is three things, each done with a `sk_live_` key: register the production database (`ablo connect apply` — the DIRECT host, never a pooler; a pooler refuses in the words of a wrong password), push the schema AHEAD of the code that needs it, and hold the right credential per runtime (server/serverless `sk_live_`; browser `pk_live_` read-only or an `authEndpoint` minting `ek_`). The live key `ablo login` stores is a RESTRICTED observe-only `rk_live_` and CANNOT push schema — a production push needs a dashboard `sk_live_` in `ABLO_API_KEY`. Gate a deploy on `npx ablo status --json` having an EMPTY `blockers` array; each blocker carries a `problem` and the one `fix`. Your agents do NOT each hold a database connection — they talk to Ablo, and Ablo holds at most 4 connections per plane (`application_name = 'ablo-direct-writer'`) however many callers write behind them, so size the database for that number and not for your agent count. Read `deployment` for the full path.
203
204
 
@@ -214,8 +215,9 @@ Import from these public paths only:
214
215
  - `@abloatai/ablo/source/drizzle` — `drizzleDataSource`.
215
216
  - `@abloatai/ablo/source/kysely` — `kyselyDataSource`.
216
217
  - `@abloatai/ablo/source/conformance` — `runDataSourceTests` to prove a custom adapter/handler.
218
+ - `@abloatai/ablo/ai-sdk` — thin AI SDK tools over typed model reads, creates, coordinated updates, and claimed deletes.
217
219
 
218
- Do not teach `/api`, `/agent`, `/ai-sdk`, `/core`, `/realtime`, or internal subpaths. (`/source` IS public it's the Data Source endpoint surface above.)
220
+ Do not teach `/api`, `/agent`, `/core`, `/realtime`, or internal subpaths. (`/source` and `/ai-sdk` are public.)
219
221
 
220
222
  ## CLI: agents run it NON-INTERACTIVELY
221
223
 
@@ -223,10 +225,10 @@ Do not teach `/api`, `/agent`, `/ai-sdk`, `/core`, `/realtime`, or internal subp
223
225
 
224
226
  - `npx ablo init --yes` (flags: `--framework`, `--auth`, `--storage replication|endpoint`, `--no-agent`, `--no-pull`, `--no-install`, `--no-login`). Generates `ablo/schema.ts` + the `Ablo({ schema, apiKey })` client. `--storage replication` (the default) pairs with `ablo connect`; `--storage endpoint` also scaffolds the `ablo/data-source.ts` fallback endpoint.
225
227
  - `npx ablo connect` connects your database via logical replication — the read path (prints the `wal_level=logical` + publication + `REPLICATION`-role SQL); `npx ablo connect register` registers it, `npx ablo connect check` validates the registered database from Ablo's own side and needs only `ABLO_API_KEY` (no database credential in your environment). `npx ablo connect apply` does the whole setup from a one-time admin connection and leaves your app holding only `ABLO_API_KEY`.
226
- - Key: see "Start here" — env → `.env.local` → ask the human to `npx ablo login`; never run `login` yourself, never copy keys by hand (`ablo push` writes `.env.local`).
228
+ - Key: see "Start here" — env → `.env.local` → ask the human to `npx ablo login`; never run `login` yourself, never copy keys by hand (`ablo dev` mints and wires the temporary branch key).
227
229
  - Adopt an existing DB: `npx ablo pull prisma [path]` / `npx ablo pull drizzle <module>`.
228
- - `npx ablo push` pushes the schema (sandbox) AND writes `ABLO_API_KEY` to `.env.local`. A PRODUCTION push (`sk_live_` key) needs `--yes`: with no TTY it REFUSES rather than deploying unattended, and interactively it demands the destination project typed by name. Destructive steps (dropped model/field, narrowed enum, lossy cast) need `--force`; a new required field on a populated table needs `--backfill model.field=value`. `npx ablo dev --no-watch` is the push-once form of the watcher; `npx ablo logs --no-follow` exits instead of tailing forever; `npx ablo mode sandbox|production` always needs the argument. `npx ablo push`/`status`/`pull`/`check`/`generate` are one-shot.
230
+ - `npx ablo dev --no-watch --branch <git-or-ci-ref>` ensures an isolated branch, mints and wires its temporary key, pushes once, and exits. Plain `dev` watches forever. `npx ablo branch check <id-or-slug>` prints lifecycle, schema/parent compatibility, datasource identity, and readiness. `npx ablo push` pushes with the already selected key and does NOT choose a branch for you. A PRODUCTION push (`sk_live_` key) needs `--yes`: with no TTY it REFUSES rather than deploying unattended, and interactively it demands the destination project typed by name. Destructive steps (dropped model/field, narrowed enum, lossy cast) need `--force`; a new required field on a populated table needs `--backfill model.field=value`. `npx ablo logs --no-follow` exits instead of tailing forever. `npx ablo push`/`status`/`pull`/`check`/`generate` are one-shot.
229
231
 
230
232
  - `npx ablo docs` lists every documentation page; `npx ablo docs <page>` prints one as markdown. These pages ship INSIDE the installed package, so they describe the version in `node_modules` and need no network. Prefer them over a docs URL whenever the project pins a version: a website always describes the newest release, so on an older pin it will hand you a call your package does not have (`retrieve`/`list` replaced `get`/`getAll`/`getCount` in 0.35.0). One-shot, safe to run unattended.
231
233
 
232
- Canonical docs to read before integrating: `quickstart`, `schema-contract`, `integration-guide`, `deployment`, `guarantees`, `client-behavior`, `data-sources`, `examples/existing-python-backend`, `api`, `examples/ai-sdk-tool`, and `examples/server-agent` — read each with `npx ablo docs <page>`. When upgrading an existing integration, read `migration` — every breaking change, what to change, and which version introduced it. When the customer's database has row-level-security policies, read `session-settings` — the identity context Ablo sets before every write, and how to map it to the setting names those policies already read.
234
+ Canonical docs to read before integrating: `quickstart`, `branch-development`, `schema-contract`, `integration-guide`, `deployment`, `guarantees`, `client-behavior`, `data-sources`, `examples/existing-python-backend`, `api`, `examples/ai-sdk-tool`, and `examples/server-agent` — read each with `npx ablo docs <page>`. When upgrading an existing integration, read `migration` — every breaking change, what to change, and which version introduced it. When the customer's database has row-level-security policies, read `session-settings` — the identity context Ablo sets before every write, and how to map it to the setting names those policies already read.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abloatai/ablo",
3
- "version": "0.37.0",
3
+ "version": "0.38.0",
4
4
  "description": "The public Ablo SDK for coordinated reads, commits, claims, observation, and reactive applications.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -70,6 +70,11 @@
70
70
  "import": "./dist/coordination.js",
71
71
  "default": "./dist/coordination.js"
72
72
  },
73
+ "./ai-sdk": {
74
+ "types": "./dist/ai-sdk.d.ts",
75
+ "import": "./dist/ai-sdk.js",
76
+ "default": "./dist/ai-sdk.js"
77
+ },
73
78
  "./wire": {
74
79
  "types": "./dist/wire.d.ts",
75
80
  "import": "./dist/wire.js",
@@ -99,6 +104,9 @@
99
104
  "test": "vitest run",
100
105
  "generate:errors": "tsx scripts/generate-error-docs.mts",
101
106
  "lint:errors": "tsx scripts/check-error-docs.mts",
107
+ "generate:openapi": "tsx --conditions=@ablo/source scripts/generate-openapi.mts",
108
+ "lint:openapi": "tsx --conditions=@ablo/source scripts/generate-openapi.mts --check",
109
+ "validate:openapi": "redocly lint ../../docs/ablo/public/openapi.json --extends=recommended --skip-rule=no-server-example.com",
102
110
  "build:docs": "node scripts/build-blume-docs.mjs",
103
111
  "lint:docs": "node scripts/check-doc-drift.mjs",
104
112
  "lint:pkg": "publint"
@@ -114,13 +122,17 @@
114
122
  "directory": "packages/ablo"
115
123
  },
116
124
  "dependencies": {
117
- "@abloatai/humans": "^0.37.0",
118
- "@abloatai/transaction": "^0.37.0"
125
+ "@abloatai/humans": "^0.38.0",
126
+ "@abloatai/transaction": "^0.38.0"
119
127
  },
120
128
  "peerDependencies": {
129
+ "ai": "^6.0.0 || ^7.0.0",
121
130
  "react": "^19.2.8"
122
131
  },
123
132
  "peerDependenciesMeta": {
133
+ "ai": {
134
+ "optional": true
135
+ },
124
136
  "react": {
125
137
  "optional": true
126
138
  }