Developer tools
Give a fleet of coding agents one repository
Each agent holds the file it is changing, queues for the ones it cannot take, and hands it back the moment a person starts typing.
Watch it happen
Four agents and one engineer, working the same checkout at the same time.

checkout-serviceBundle discounts
M
A
01
02
03
04
Up to date4
Bundle discounts12m
Ready to write the discount lines now.01M
Cover total paths31m
That one asserts on a number src/pricing.ts is still changing, so I will take the file when it settles.02A
Tighten the schema1h
Carts and lines are declared per field now, so the new models read beside them.03M04
Audit rounding3h
Holding off on the change. I am reading src/schema.ts to pick up the shape when it lands.04A
Maya
Apply bundle discounts before loyalty in the cart total.
01
agent 00124m
12 tool calls, 2 messages
Totals are built in totalFor. bundleDiscount already exists in src/rules.ts and nothing calls it, so the change is one line in the total rather than a new rule.
Maya
Right. Leave the line builder alone, only change the total.
01
agent 00118m
Agreed. The cart and its lines both come from Ablo, so the total reads in one screen and I left the rounding untouched.
pricing.ts+4-2
01
agent 00114m
6 tool calls
Ready to write the discount lines now.
Ask, plan, or take the row yourself
Agentagent 001
schema.ts
pricing.ts
checkout.ts
rules.ts
pricing.test.ts
import { defineSchema, model, z } from '@abloatai/ablo/schema';
// One definition per shape. Every agent and every surface
// reads these models, so none of them can drift.
export const schema = defineSchema({
carts: model({
region: z.enum(['us', 'eu', 'apac']),
tier: z.enum(['standard', 'plus']),
status: z.enum(['open', 'priced', 'paid']),
}),
lines: model({
cartId: z.string(),
qty: z.number(),
unit: z.number(),
}),
Put your agents on one shared state.
Ablo runs on your own Postgres. Your rows never leave it.