@abloatai/ablo 0.34.1 → 0.35.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.
Files changed (483) hide show
  1. package/AGENTS.md +2 -1
  2. package/CHANGELOG.md +674 -5
  3. package/README.md +39 -22
  4. package/dist/BaseSyncedStore.d.ts +152 -44
  5. package/dist/BaseSyncedStore.js +300 -184
  6. package/dist/Database.d.ts +9 -24
  7. package/dist/Database.js +37 -22
  8. package/dist/InstanceCache.d.ts +25 -4
  9. package/dist/InstanceCache.js +48 -15
  10. package/dist/LazyReferenceCollection.d.ts +3 -3
  11. package/dist/LazyReferenceCollection.js +4 -4
  12. package/dist/Model.d.ts +6 -6
  13. package/dist/Model.js +10 -10
  14. package/dist/ModelRegistry.d.ts +4 -4
  15. package/dist/ModelRegistry.js +3 -3
  16. package/dist/{SyncEngineContext.d.ts → RuntimeContext.d.ts} +20 -13
  17. package/dist/{SyncEngineContext.js → RuntimeContext.js} +11 -12
  18. package/dist/SyncClient.d.ts +42 -32
  19. package/dist/SyncClient.js +166 -110
  20. package/dist/ai-sdk/coordinatedTool.d.ts +2 -2
  21. package/dist/ai-sdk/coordinatedTool.js +1 -1
  22. package/dist/ai-sdk/coordinationContext.d.ts +2 -2
  23. package/dist/ai-sdk/coordinationContext.js +1 -1
  24. package/dist/ai-sdk/wrap.d.ts +3 -3
  25. package/dist/ai-sdk/wrap.js +2 -2
  26. package/dist/auth/index.d.ts +1 -156
  27. package/dist/auth/index.js +8 -301
  28. package/dist/cli.cjs +3344 -1073
  29. package/dist/client/Ablo.d.ts +42 -287
  30. package/dist/client/Ablo.js +118 -963
  31. package/dist/client/abloClient.d.ts +309 -0
  32. package/dist/client/abloClient.js +13 -0
  33. package/dist/client/clientPrelude.d.ts +52 -0
  34. package/dist/client/clientPrelude.js +60 -0
  35. package/dist/client/consoleLogger.d.ts +2 -2
  36. package/dist/client/coreClient.d.ts +60 -0
  37. package/dist/client/coreClient.js +118 -0
  38. package/dist/client/createInternalComponents.d.ts +4 -4
  39. package/dist/client/createInternalComponents.js +9 -8
  40. package/dist/client/createModelProxy.d.ts +78 -373
  41. package/dist/client/createModelProxy.js +114 -86
  42. package/dist/client/humans.d.ts +48 -0
  43. package/dist/client/humans.js +52 -0
  44. package/dist/client/modelRegistration.d.ts +1 -1
  45. package/dist/client/modelRegistration.js +9 -9
  46. package/dist/client/options.d.ts +73 -17
  47. package/dist/client/reactiveEngine.d.ts +48 -0
  48. package/dist/client/reactiveEngine.js +910 -0
  49. package/dist/client/resourceTypes.d.ts +9 -250
  50. package/dist/client/resourceTypes.js +8 -5
  51. package/dist/client/schemaConfig.d.ts +4 -4
  52. package/dist/client/schemaConfig.js +6 -2
  53. package/dist/client/validateAbloOptions.d.ts +3 -2
  54. package/dist/client/validateAbloOptions.js +1 -1
  55. package/dist/client/wsMutationExecutor.d.ts +3 -3
  56. package/dist/client/wsMutationExecutor.js +3 -3
  57. package/dist/context.d.ts +9 -9
  58. package/dist/context.js +10 -9
  59. package/dist/coordination/ClaimLog.d.ts +26 -0
  60. package/dist/coordination/ClaimLog.js +32 -0
  61. package/dist/coordination/index.d.ts +1 -15
  62. package/dist/coordination/index.js +8 -31
  63. package/dist/core/DatabaseManager.js +1 -1
  64. package/dist/core/QueryView.d.ts +1 -1
  65. package/dist/core/QueryView.js +1 -1
  66. package/dist/core/StoreManager.d.ts +4 -23
  67. package/dist/core/StoreManager.js +5 -55
  68. package/dist/core/index.d.ts +2 -2
  69. package/dist/core/index.js +2 -2
  70. package/dist/core/storeContract.d.ts +2 -2
  71. package/dist/docs/catalog.d.ts +72 -0
  72. package/dist/docs/catalog.js +227 -0
  73. package/dist/docs/index.d.ts +10 -0
  74. package/dist/docs/index.js +10 -0
  75. package/dist/environment.d.ts +1 -40
  76. package/dist/environment.js +8 -37
  77. package/dist/index.d.ts +40 -34
  78. package/dist/index.js +26 -20
  79. package/dist/interfaces/index.d.ts +44 -134
  80. package/dist/keys/index.d.ts +1 -77
  81. package/dist/keys/index.js +8 -190
  82. package/dist/mutators/{RecordingTransaction.d.ts → RecordingMutation.d.ts} +4 -4
  83. package/dist/mutators/{RecordingTransaction.js → RecordingMutation.js} +2 -2
  84. package/dist/mutators/Transaction.d.ts +1 -1
  85. package/dist/mutators/Transaction.js +1 -1
  86. package/dist/mutators/UndoManager.d.ts +6 -6
  87. package/dist/mutators/UndoManager.js +5 -5
  88. package/dist/mutators/defineMutators.d.ts +3 -3
  89. package/dist/mutators/defineMutators.js +1 -1
  90. package/dist/mutators/inverseOp.js +2 -2
  91. package/dist/mutators/mutateActions.d.ts +3 -3
  92. package/dist/mutators/mutateActions.js +1 -1
  93. package/dist/mutators/readerActions.d.ts +1 -1
  94. package/dist/mutators/undoApply.d.ts +1 -1
  95. package/dist/mutators/undoApply.js +1 -1
  96. package/dist/policy/index.d.ts +2 -2
  97. package/dist/policy/index.js +1 -1
  98. package/dist/query/client.d.ts +2 -2
  99. package/dist/query/client.js +4 -4
  100. package/dist/query/types.d.ts +6 -41
  101. package/dist/query/types.js +2 -2
  102. package/dist/react/AbloProvider.d.ts +6 -8
  103. package/dist/react/AbloProvider.js +5 -7
  104. package/dist/react/context.d.ts +1 -1
  105. package/dist/react/context.js +1 -1
  106. package/dist/react/index.d.ts +5 -5
  107. package/dist/react/index.js +3 -3
  108. package/dist/react/internalContext.d.ts +1 -1
  109. package/dist/react/useAblo.d.ts +3 -3
  110. package/dist/react/useAblo.js +1 -1
  111. package/dist/react/useCurrentUserId.js +1 -1
  112. package/dist/react/useErrorListener.js +1 -1
  113. package/dist/react/useMutationFailureListener.d.ts +2 -2
  114. package/dist/react/useMutationFailureListener.js +1 -1
  115. package/dist/react/useMutators.d.ts +3 -3
  116. package/dist/react/useMutators.js +3 -3
  117. package/dist/react/useUndoScope.d.ts +5 -5
  118. package/dist/react/useUndoScope.js +1 -1
  119. package/dist/schema/coordination.d.ts +69 -10
  120. package/dist/schema/coordination.js +86 -9
  121. package/dist/schema/ddl.js +2 -2
  122. package/dist/schema/diff.d.ts +1 -1
  123. package/dist/schema/generate.js +1 -1
  124. package/dist/schema/index.d.ts +10 -10
  125. package/dist/schema/index.js +18 -18
  126. package/dist/schema/queries.d.ts +27 -27
  127. package/dist/schema/queries.js +23 -23
  128. package/dist/schema/select.d.ts +3 -3
  129. package/dist/schema/select.js +3 -3
  130. package/dist/schema/serialize.d.ts +15 -6
  131. package/dist/schema/serialize.js +17 -3
  132. package/dist/schema/sugar.d.ts +6 -7
  133. package/dist/schema/sugar.js +9 -12
  134. package/dist/schema/syncDeltaRow.d.ts +4 -152
  135. package/dist/schema/syncDeltaRow.js +4 -105
  136. package/dist/server/adapter.d.ts +18 -1
  137. package/dist/server/commit.d.ts +10 -16
  138. package/dist/server/index.d.ts +1 -1
  139. package/dist/server/index.js +1 -1
  140. package/dist/server/readConfig.d.ts +1 -1
  141. package/dist/source/adapters/drizzle.d.ts +1 -1
  142. package/dist/source/adapters/drizzle.js +2 -2
  143. package/dist/source/adapters/kysely.d.ts +1 -1
  144. package/dist/source/adapters/kysely.js +1 -1
  145. package/dist/source/adapters/kyselyMutationCore.d.ts +1 -1
  146. package/dist/source/adapters/kyselyMutationCore.js +2 -2
  147. package/dist/source/adapters/memory.js +1 -1
  148. package/dist/source/adapters/prisma.d.ts +8 -3
  149. package/dist/source/adapters/prisma.js +1 -1
  150. package/dist/source/connector.js +1 -1
  151. package/dist/source/connectorProtocol.d.ts +2 -8
  152. package/dist/source/connectorProtocol.js +3 -2
  153. package/dist/source/contract.d.ts +29 -17
  154. package/dist/source/contract.js +27 -22
  155. package/dist/source/factory.d.ts +1 -1
  156. package/dist/source/footprint.d.ts +111 -0
  157. package/dist/source/footprint.js +0 -0
  158. package/dist/source/idempotency.js +2 -2
  159. package/dist/source/index.d.ts +1 -0
  160. package/dist/source/index.js +3 -0
  161. package/dist/source/next.d.ts +1 -1
  162. package/dist/source/signing.d.ts +9 -2
  163. package/dist/source/signing.js +4 -1
  164. package/dist/source/types.d.ts +6 -4
  165. package/dist/source/types.js +1 -1
  166. package/dist/stores/ObjectStore.d.ts +1 -1
  167. package/dist/stores/SyncActionStore.d.ts +1 -1
  168. package/dist/stores/SyncActionStore.js +2 -10
  169. package/dist/stores/syncAction.d.ts +26 -0
  170. package/dist/stores/syncAction.js +16 -0
  171. package/dist/surface.d.ts +3 -3
  172. package/dist/surface.js +6 -4
  173. package/dist/sync/BootstrapFetcher.d.ts +123 -6
  174. package/dist/sync/BootstrapFetcher.js +492 -66
  175. package/dist/sync/ConnectionManager.d.ts +6 -198
  176. package/dist/sync/ConnectionManager.js +6 -677
  177. package/dist/sync/OnDemandLoader.d.ts +2 -2
  178. package/dist/sync/OnDemandLoader.js +60 -21
  179. package/dist/sync/SubscriptionManager.d.ts +13 -2
  180. package/dist/sync/SubscriptionManager.js +23 -5
  181. package/dist/sync/SyncWebSocket.d.ts +27 -510
  182. package/dist/sync/SyncWebSocket.js +76 -954
  183. package/dist/sync/awaitClaimGrant.d.ts +4 -44
  184. package/dist/sync/awaitClaimGrant.js +4 -109
  185. package/dist/sync/commitFrames.d.ts +6 -40
  186. package/dist/sync/commitFrames.js +6 -97
  187. package/dist/sync/contextPorts.d.ts +18 -0
  188. package/dist/sync/contextPorts.js +31 -0
  189. package/dist/sync/createClaimStream.d.ts +5 -49
  190. package/dist/sync/createClaimStream.js +5 -469
  191. package/dist/sync/createPresenceStream.d.ts +26 -4
  192. package/dist/sync/createPresenceStream.js +28 -20
  193. package/dist/sync/createSnapshot.d.ts +2 -2
  194. package/dist/sync/createSnapshot.js +1 -1
  195. package/dist/sync/credentialLifecycle.d.ts +5 -173
  196. package/dist/sync/credentialLifecycle.js +5 -320
  197. package/dist/sync/deltaPipeline.d.ts +1 -1
  198. package/dist/sync/participants.d.ts +5 -4
  199. package/dist/sync/participants.js +29 -22
  200. package/dist/sync/schemaDrift.d.ts +55 -0
  201. package/dist/sync/schemaDrift.js +53 -0
  202. package/dist/sync/schemas.d.ts +21 -32
  203. package/dist/sync/schemas.js +26 -17
  204. package/dist/sync/syncPlan.d.ts +3 -3
  205. package/dist/sync/wsFrameHandlers.d.ts +6 -114
  206. package/dist/sync/wsFrameHandlers.js +6 -392
  207. package/dist/testing/fixtures/bootstrap.d.ts +1 -1
  208. package/dist/testing/fixtures/deltas.d.ts +1 -1
  209. package/dist/testing/fixtures/httpResponses.d.ts +70 -0
  210. package/dist/testing/fixtures/httpResponses.js +90 -0
  211. package/dist/testing/fixtures/models.js +1 -1
  212. package/dist/testing/helpers/wait.js +1 -1
  213. package/dist/testing/mocks/MockMutationExecutor.d.ts +2 -2
  214. package/dist/testing/mocks/MockMutationExecutor.js +8 -14
  215. package/dist/testing/mocks/MockSyncContext.d.ts +11 -11
  216. package/dist/testing/mocks/MockSyncContext.js +10 -9
  217. package/dist/testing/mocks/MockSyncStore.js +1 -1
  218. package/dist/testing/mocks/MockWebSocket.d.ts +2 -2
  219. package/dist/transaction/ablo.d.ts +88 -0
  220. package/dist/transaction/ablo.js +33 -0
  221. package/dist/{client/auth.d.ts → transaction/auth/apiKey.d.ts} +43 -8
  222. package/dist/{client/auth.js → transaction/auth/apiKey.js} +19 -0
  223. package/dist/transaction/auth/bootstrapScope.d.ts +15 -0
  224. package/dist/transaction/auth/bootstrapScope.js +1 -0
  225. package/dist/transaction/auth/capability.d.ts +177 -0
  226. package/dist/transaction/auth/capability.js +199 -0
  227. package/dist/{auth → transaction/auth}/credentialSource.d.ts +8 -1
  228. package/dist/{client → transaction/auth}/identity.d.ts +8 -7
  229. package/dist/{client → transaction/auth}/identity.js +1 -1
  230. package/dist/transaction/auth/index.d.ts +162 -0
  231. package/dist/transaction/auth/index.js +304 -0
  232. package/dist/{auth → transaction/auth}/schemas.d.ts +1 -1
  233. package/dist/{auth → transaction/auth}/schemas.js +13 -13
  234. package/dist/{client → transaction/auth}/sessionMint.d.ts +8 -8
  235. package/dist/{client → transaction/auth}/sessionMint.js +4 -7
  236. package/dist/transaction/coordination/awaitClaimGrant.d.ts +49 -0
  237. package/dist/transaction/coordination/awaitClaimGrant.js +112 -0
  238. package/dist/transaction/coordination/claimMeta.d.ts +49 -0
  239. package/dist/transaction/coordination/claimMeta.js +52 -0
  240. package/dist/transaction/coordination/createClaimStream.d.ts +64 -0
  241. package/dist/transaction/coordination/createClaimStream.js +475 -0
  242. package/dist/transaction/coordination/events.d.ts +74 -0
  243. package/dist/transaction/coordination/events.js +7 -0
  244. package/dist/transaction/coordination/index.d.ts +19 -0
  245. package/dist/transaction/coordination/index.js +44 -0
  246. package/dist/transaction/coordination/locator.d.ts +83 -0
  247. package/dist/transaction/coordination/locator.js +82 -0
  248. package/dist/transaction/coordination/schema.d.ts +1473 -0
  249. package/dist/{coordination → transaction/coordination}/schema.js +490 -55
  250. package/dist/transaction/coordination/targetConflict.d.ts +2 -0
  251. package/dist/transaction/coordination/targetConflict.js +103 -0
  252. package/dist/{coordination → transaction/coordination}/trace.d.ts +7 -18
  253. package/dist/{coordination → transaction/coordination}/trace.js +18 -25
  254. package/dist/transaction/durableWrites.d.ts +62 -0
  255. package/dist/{client → transaction}/durableWrites.js +28 -3
  256. package/dist/transaction/environment.d.ts +105 -0
  257. package/dist/transaction/environment.js +108 -0
  258. package/dist/{errorCodes.d.ts → transaction/errorCodes.d.ts} +11 -11
  259. package/dist/{errorCodes.js → transaction/errorCodes.js} +35 -12
  260. package/dist/{errors.d.ts → transaction/errors.d.ts} +37 -13
  261. package/dist/{errors.js → transaction/errors.js} +85 -16
  262. package/dist/transaction/index.d.ts +20 -0
  263. package/dist/transaction/index.js +20 -0
  264. package/dist/transaction/keys/index.d.ts +87 -0
  265. package/dist/transaction/keys/index.js +207 -0
  266. package/dist/transaction/log/syncDeltaRow.d.ts +158 -0
  267. package/dist/transaction/log/syncDeltaRow.js +95 -0
  268. package/dist/{sync/syncPosition.d.ts → transaction/logPosition.d.ts} +22 -8
  269. package/dist/{sync/syncPosition.js → transaction/logPosition.js} +15 -6
  270. package/dist/transaction/logger.d.ts +16 -0
  271. package/dist/transaction/logger.js +7 -0
  272. package/dist/transaction/observability.d.ts +53 -0
  273. package/dist/transaction/observability.js +19 -0
  274. package/dist/transaction/plugin.d.ts +192 -0
  275. package/dist/transaction/plugin.js +87 -0
  276. package/dist/{policy → transaction/policy}/types.d.ts +3 -3
  277. package/dist/{policy → transaction/policy}/types.js +2 -0
  278. package/dist/transaction/resources/httpResources.d.ts +266 -0
  279. package/dist/transaction/resources/httpResources.js +7 -0
  280. package/dist/transaction/resources/modelOperations.d.ts +319 -0
  281. package/dist/transaction/resources/modelOperations.js +12 -0
  282. package/dist/transaction/resources/mutationOptions.d.ts +66 -0
  283. package/dist/transaction/resources/mutationOptions.js +9 -0
  284. package/dist/transaction/resources/where.d.ts +85 -0
  285. package/dist/transaction/resources/where.js +70 -0
  286. package/dist/{client → transaction/resources}/writeOptionsSchema.d.ts +2 -6
  287. package/dist/{client → transaction/resources}/writeOptionsSchema.js +9 -5
  288. package/dist/{schema → transaction/schema}/field.d.ts +5 -5
  289. package/dist/{schema → transaction/schema}/field.js +5 -5
  290. package/dist/transaction/schema/loadStrategy.d.ts +45 -0
  291. package/dist/transaction/schema/loadStrategy.js +46 -0
  292. package/dist/{schema → transaction/schema}/model.d.ts +50 -35
  293. package/dist/{schema → transaction/schema}/model.js +30 -20
  294. package/dist/transaction/schema/openapi.d.ts +57 -0
  295. package/dist/transaction/schema/openapi.js +340 -0
  296. package/dist/{schema → transaction/schema}/relation.d.ts +14 -14
  297. package/dist/{schema → transaction/schema}/relation.js +7 -7
  298. package/dist/{schema → transaction/schema}/residency.d.ts +0 -9
  299. package/dist/{schema → transaction/schema}/residency.js +0 -5
  300. package/dist/{schema → transaction/schema}/roles.d.ts +5 -5
  301. package/dist/{schema → transaction/schema}/roles.js +5 -5
  302. package/dist/{schema → transaction/schema}/schema.d.ts +12 -10
  303. package/dist/{schema → transaction/schema}/schema.js +4 -3
  304. package/dist/{schema → transaction/schema}/tenancy.d.ts +1 -1
  305. package/dist/{schema → transaction/schema}/tenancy.js +7 -4
  306. package/dist/transaction/transactionLayer.d.ts +82 -0
  307. package/dist/transaction/transactionLayer.js +24 -0
  308. package/dist/{transactions → transaction/transactions/settlement}/commitEnvelope.d.ts +4 -5
  309. package/dist/{transactions → transaction/transactions/settlement}/commitEnvelope.js +9 -13
  310. package/dist/{transactions → transaction/transactions/settlement}/httpCommitEnvelope.d.ts +9 -2
  311. package/dist/{transactions → transaction/transactions/settlement}/httpCommitEnvelope.js +5 -9
  312. package/dist/{transactions/durableWriteStore.d.ts → transaction/transactions/settlement/pendingWrite.d.ts} +10 -36
  313. package/dist/transaction/transactions/settlement/pendingWrite.js +20 -0
  314. package/dist/transaction/transport/commitFrames.d.ts +90 -0
  315. package/dist/transaction/transport/commitFrames.js +134 -0
  316. package/dist/transaction/transport/connectionManager.d.ts +215 -0
  317. package/dist/transaction/transport/connectionManager.js +673 -0
  318. package/dist/transaction/transport/credentialLifecycle.d.ts +177 -0
  319. package/dist/transaction/transport/credentialLifecycle.js +324 -0
  320. package/dist/{sync → transaction/transport}/heartbeat.d.ts +3 -1
  321. package/dist/{sync → transaction/transport}/heartbeat.js +6 -4
  322. package/dist/{client → transaction/transport}/httpClient.d.ts +59 -16
  323. package/dist/{client → transaction/transport}/httpClient.js +5 -5
  324. package/dist/transaction/transport/httpOptions.d.ts +33 -0
  325. package/dist/transaction/transport/httpOptions.js +12 -0
  326. package/dist/{client → transaction/transport}/httpTransport.js +171 -85
  327. package/dist/{sync/NetworkProbe.d.ts → transaction/transport/networkProbe.d.ts} +7 -4
  328. package/dist/{sync/NetworkProbe.js → transaction/transport/networkProbe.js} +14 -13
  329. package/dist/transaction/transport/wsFrameHandlers.d.ts +128 -0
  330. package/dist/transaction/transport/wsFrameHandlers.js +429 -0
  331. package/dist/transaction/transport/wsTransport.d.ts +576 -0
  332. package/dist/transaction/transport/wsTransport.js +1017 -0
  333. package/dist/transaction/types/assertExact.d.ts +17 -0
  334. package/dist/transaction/types/assertExact.js +1 -0
  335. package/dist/{types → transaction/types}/global.d.ts +17 -2
  336. package/dist/{types → transaction/types}/global.js +2 -1
  337. package/dist/{types → transaction/types}/index.d.ts +14 -46
  338. package/dist/{types → transaction/types}/index.js +7 -16
  339. package/dist/{types → transaction/types}/streams.d.ts +63 -45
  340. package/dist/{utils → transaction/utils}/json.d.ts +18 -0
  341. package/dist/transaction/utils/json.js +276 -0
  342. package/dist/transaction/wire/accountResponses.d.ts +351 -0
  343. package/dist/transaction/wire/accountResponses.js +255 -0
  344. package/dist/transaction/wire/auth.d.ts +49 -0
  345. package/dist/transaction/wire/auth.js +57 -0
  346. package/dist/transaction/wire/claimEvent.d.ts +76 -0
  347. package/dist/transaction/wire/claimEvent.js +73 -0
  348. package/dist/transaction/wire/claims.d.ts +463 -0
  349. package/dist/transaction/wire/claims.js +229 -0
  350. package/dist/{wire → transaction/wire}/commit.d.ts +125 -193
  351. package/dist/{wire → transaction/wire}/commit.js +68 -47
  352. package/dist/{wire → transaction/wire}/delta.d.ts +66 -17
  353. package/dist/{wire → transaction/wire}/delta.js +37 -13
  354. package/dist/transaction/wire/errorEnvelope.d.ts +72 -0
  355. package/dist/{wire → transaction/wire}/errorEnvelope.js +36 -5
  356. package/dist/transaction/wire/feedCursor.d.ts +60 -0
  357. package/dist/transaction/wire/feedCursor.js +82 -0
  358. package/dist/transaction/wire/feedEvent.d.ts +177 -0
  359. package/dist/transaction/wire/feedEvent.js +39 -0
  360. package/dist/transaction/wire/frames.d.ts +194 -0
  361. package/dist/transaction/wire/frames.js +50 -0
  362. package/dist/transaction/wire/inboundFrames.d.ts +552 -0
  363. package/dist/transaction/wire/inboundFrames.js +116 -0
  364. package/dist/transaction/wire/index.d.ts +50 -0
  365. package/dist/transaction/wire/index.js +74 -0
  366. package/dist/{wire → transaction/wire}/listEnvelope.d.ts +13 -14
  367. package/dist/transaction/wire/listEnvelope.js +42 -0
  368. package/dist/transaction/wire/modelResponses.d.ts +85 -0
  369. package/dist/transaction/wire/modelResponses.js +43 -0
  370. package/dist/transactions/{TransactionQueue.d.ts → mutations/MutationQueue.d.ts} +79 -38
  371. package/dist/transactions/{TransactionQueue.js → mutations/MutationQueue.js} +110 -59
  372. package/dist/transactions/{TransactionStore.d.ts → mutations/MutationStore.d.ts} +8 -8
  373. package/dist/transactions/{TransactionStore.js → mutations/MutationStore.js} +2 -2
  374. package/dist/transactions/{coalesceRules.d.ts → mutations/coalesceRules.d.ts} +10 -10
  375. package/dist/transactions/{coalesceRules.js → mutations/coalesceRules.js} +1 -1
  376. package/dist/transactions/mutations/commitLatency.d.ts +52 -0
  377. package/dist/transactions/mutations/commitLatency.js +130 -0
  378. package/dist/transactions/{commitOutboxStore.d.ts → mutations/commitOutboxStore.d.ts} +1 -5
  379. package/dist/transactions/{commitOutboxStore.js → mutations/commitOutboxStore.js} +1 -1
  380. package/dist/transactions/{commitPayload.d.ts → mutations/commitPayload.d.ts} +16 -15
  381. package/dist/transactions/{commitPayload.js → mutations/commitPayload.js} +12 -12
  382. package/dist/transactions/{deltaConfirmation.d.ts → mutations/deltaConfirmation.d.ts} +11 -11
  383. package/dist/transactions/{deltaConfirmation.js → mutations/deltaConfirmation.js} +7 -7
  384. package/dist/transactions/mutations/durableWriteStore.d.ts +14 -0
  385. package/dist/transactions/mutations/durableWriteStore.js +12 -0
  386. package/dist/transactions/{optimisticApply.d.ts → mutations/optimisticApply.d.ts} +7 -7
  387. package/dist/transactions/{replayValidation.d.ts → mutations/replayValidation.d.ts} +3 -3
  388. package/dist/transactions/{replayValidation.js → mutations/replayValidation.js} +4 -3
  389. package/dist/utils/mobxSetup.d.ts +1 -1
  390. package/dist/utils/mobxSetup.js +5 -2
  391. package/dist/webhooks/events.d.ts +2 -2
  392. package/dist/wire/index.d.ts +1 -34
  393. package/dist/wire/index.js +8 -49
  394. package/docs/agent-messaging.md +3 -3
  395. package/docs/agents.md +19 -12
  396. package/docs/api-keys.md +8 -4
  397. package/docs/api.md +22 -18
  398. package/docs/audit.md +2 -0
  399. package/docs/cli.md +31 -3
  400. package/docs/client-behavior.md +8 -6
  401. package/docs/concurrency-convention.md +30 -24
  402. package/docs/coordination.md +48 -38
  403. package/docs/data-sources.md +3 -1
  404. package/docs/debugging.md +5 -3
  405. package/docs/deployment.md +267 -0
  406. package/docs/examples/agent-human.md +49 -42
  407. package/docs/examples/ai-sdk-tool.md +69 -44
  408. package/docs/examples/existing-python-backend.md +8 -6
  409. package/docs/examples/nextjs.md +129 -47
  410. package/docs/examples/scoped-agent.md +45 -44
  411. package/docs/examples/server-agent.md +46 -26
  412. package/docs/groups.md +32 -29
  413. package/docs/guarantees.md +4 -2
  414. package/docs/how-it-works.md +9 -7
  415. package/docs/idempotency.md +126 -0
  416. package/docs/identity.md +58 -54
  417. package/docs/index.md +172 -86
  418. package/docs/integration-guide.md +17 -16
  419. package/docs/interaction-model.md +6 -4
  420. package/docs/mcp.md +41 -16
  421. package/docs/migration.md +63 -5
  422. package/docs/operating-on-your-database.md +3 -1
  423. package/docs/projects.md +2 -0
  424. package/docs/quickstart.md +22 -5
  425. package/docs/react.md +12 -10
  426. package/docs/schema-contract.md +5 -3
  427. package/docs/session-settings.md +108 -0
  428. package/docs/sessions.md +3 -1
  429. package/docs/webhooks.md +3 -1
  430. package/llms.txt +47 -17
  431. package/package.json +10 -8
  432. package/dist/agent/Agent.d.ts +0 -366
  433. package/dist/agent/Agent.js +0 -514
  434. package/dist/agent/index.d.ts +0 -115
  435. package/dist/agent/index.js +0 -128
  436. package/dist/agent/session.d.ts +0 -93
  437. package/dist/agent/session.js +0 -149
  438. package/dist/agent/types.d.ts +0 -68
  439. package/dist/agent/types.js +0 -9
  440. package/dist/client/durableWrites.d.ts +0 -21
  441. package/dist/coordination/schema.d.ts +0 -722
  442. package/dist/schema/openapi.d.ts +0 -29
  443. package/dist/schema/openapi.js +0 -124
  444. package/dist/transactions/durableWriteStore.js +0 -30
  445. package/dist/utils/json.js +0 -88
  446. package/dist/wire/errorEnvelope.d.ts +0 -55
  447. package/dist/wire/frames.d.ts +0 -197
  448. package/dist/wire/frames.js +0 -49
  449. package/dist/wire/listEnvelope.js +0 -18
  450. /package/dist/{client → transaction/auth}/credentialEndpoint.d.ts +0 -0
  451. /package/dist/{client → transaction/auth}/credentialEndpoint.js +0 -0
  452. /package/dist/{auth → transaction/auth}/credentialPolicy.d.ts +0 -0
  453. /package/dist/{auth → transaction/auth}/credentialPolicy.js +0 -0
  454. /package/dist/{auth → transaction/auth}/credentialSource.js +0 -0
  455. /package/dist/{client → transaction/auth}/hostedEndpoints.d.ts +0 -0
  456. /package/dist/{client → transaction/auth}/hostedEndpoints.js +0 -0
  457. /package/dist/{client → transaction/coordination}/claimHeartbeatLoop.d.ts +0 -0
  458. /package/dist/{client → transaction/coordination}/claimHeartbeatLoop.js +0 -0
  459. /package/dist/{client → transaction}/persistence.d.ts +0 -0
  460. /package/dist/{client → transaction}/persistence.js +0 -0
  461. /package/dist/{client → transaction/resources}/functionalUpdate.d.ts +0 -0
  462. /package/dist/{client → transaction/resources}/functionalUpdate.js +0 -0
  463. /package/dist/{transactions → transaction/transactions/settlement}/idempotencyKey.d.ts +0 -0
  464. /package/dist/{transactions → transaction/transactions/settlement}/idempotencyKey.js +0 -0
  465. /package/dist/{client → transaction/transport}/httpTransport.d.ts +0 -0
  466. /package/dist/{types → transaction/types}/modelData.d.ts +0 -0
  467. /package/dist/{types → transaction/types}/modelData.js +0 -0
  468. /package/dist/{types → transaction/types}/participant.d.ts +0 -0
  469. /package/dist/{types → transaction/types}/participant.js +0 -0
  470. /package/dist/{types → transaction/types}/streams.js +0 -0
  471. /package/dist/{utils → transaction/utils}/asyncIterator.d.ts +0 -0
  472. /package/dist/{utils → transaction/utils}/asyncIterator.js +0 -0
  473. /package/dist/{utils → transaction/utils}/duration.d.ts +0 -0
  474. /package/dist/{utils → transaction/utils}/duration.js +0 -0
  475. /package/dist/{wire → transaction/wire}/bootstrapReason.d.ts +0 -0
  476. /package/dist/{wire → transaction/wire}/bootstrapReason.js +0 -0
  477. /package/dist/{wire → transaction/wire}/protocol.d.ts +0 -0
  478. /package/dist/{wire → transaction/wire}/protocol.js +0 -0
  479. /package/dist/{wire → transaction/wire}/protocolVersion.d.ts +0 -0
  480. /package/dist/{wire → transaction/wire}/protocolVersion.js +0 -0
  481. /package/dist/transactions/{UnconfirmedWrites.d.ts → mutations/UnconfirmedWrites.d.ts} +0 -0
  482. /package/dist/transactions/{UnconfirmedWrites.js → mutations/UnconfirmedWrites.js} +0 -0
  483. /package/dist/transactions/{optimisticApply.js → mutations/optimisticApply.js} +0 -0
@@ -1,11 +1,13 @@
1
1
  # Integration Guide
2
2
 
3
- If humans and AI agents both edit the same records in your app, they overwrite
4
- each other and there's no good place to coordinate. Ablo gives them one shared,
5
- typed write path the same `ablo.<model>.update(...)` call for a React
6
- component, a server action, a background worker, or an agent and reconciles the
7
- edits. This guide adds it to a product that already has a backend and database,
8
- one model at a time.
3
+ > The canonical end-to-end integration, added to an existing product one model at a time.
4
+
5
+ When several AI agents edit the same records in your app — alongside any people
6
+ watching them work they overwrite each other, and there is no good place to
7
+ coordinate. Ablo gives them one shared, typed write path: the same
8
+ `ablo.<model>.update(...)` call from an agent, a background worker, a server
9
+ action, or a React component. This guide adds it to a product that already has a
10
+ backend and a database, one model at a time.
9
11
 
10
12
  Three things hold no matter which actor is writing:
11
13
 
@@ -79,7 +81,7 @@ and write path are ready for production.
79
81
  When handing this to a coding agent, give it a concrete target:
80
82
 
81
83
  ```txt
82
- Add Ablo to this app for one model that humans and agents both edit.
84
+ Add Ablo to this app for one model your agents edit.
83
85
  Use the org sandbox sk_test_* key. Declare schema, add the Ablo client, replace
84
86
  one write with ablo.<model>.update(..., { readAt, onStale: 'reject',
85
87
  wait: 'confirmed' }), and add a smoke test for two concurrent writers.
@@ -139,7 +141,6 @@ model(
139
141
  {
140
142
  /* fields */
141
143
  },
142
- /* relations */ {},
143
144
  {
144
145
  // Axis 1 — `policy`: who may READ a row (tenant isolation / RLS). A
145
146
  // row-local `organization_id` column is the default, so you omit this for
@@ -256,7 +257,7 @@ refreshes before expiry.
256
257
  Reads come in two flavors, and you pick based on whether you can wait.
257
258
  `retrieve({ id })` and `list({ where })` hit the server (and hydrate the local
258
259
  store) — they're async, so you `await` them. `get(id)` (positional),
259
- `getAll({ where })`, and `getCount({ where })` read the already-synced local
260
+ `local.list({ where })`, and `local.count({ where })` read the already-synced local
260
261
  graph synchronously, so they're the ones you call in render — and the ones you
261
262
  use inside a `useAblo` selector, never the async `retrieve`/`list`.
262
263
 
@@ -270,12 +271,12 @@ const report = await ablo.weatherReports.retrieve({ id: 'report_stockholm' });
270
271
  if (!report) throw new Error('report not found');
271
272
  ```
272
273
 
273
- Use `get`, `getAll`, and `getCount` for synchronous local-graph reads after
274
+ Use `local.retrieve`, `local.list`, and `local.count` for synchronous local-graph reads after
274
275
  data has synced.
275
276
 
276
277
  ```ts
277
- const report = ablo.weatherReports.get('report_stockholm');
278
- const activeReports = ablo.weatherReports.getAll({
278
+ const report = ablo.weatherReports.local.retrieve('report_stockholm');
279
+ const activeReports = ablo.weatherReports.local.list({
279
280
  where: { projectId: 'proj_123' },
280
281
  filter: (report) => report.status !== 'ready',
281
282
  orderBy: { updatedAt: 'desc' },
@@ -295,7 +296,7 @@ export function ReportRow({
295
296
  }: {
296
297
  report: { id: string; location: string; status: string };
297
298
  }) {
298
- const report = useAblo((ablo) => ablo.weatherReports.get(serverReport.id)) ?? serverReport;
299
+ const report = useAblo((ablo) => ablo.weatherReports.local.retrieve(serverReport.id)) ?? serverReport;
299
300
  const active = useAblo((ablo) => ablo.weatherReports.claim.state({ id: serverReport.id }));
300
301
 
301
302
  return <button disabled={Boolean(active) || report.status === 'ready'}>{report.location}</button>;
@@ -375,7 +376,7 @@ The migration can be gradual:
375
376
 
376
377
  1. Declare schema for one model, such as `reports`.
377
378
  2. Keep existing server loads for first paint.
378
- 3. Add `useAblo((ablo) => ablo.weatherReports.get(id)) ?? serverReport` for live rows.
379
+ 3. Add `useAblo((ablo) => ablo.weatherReports.local.retrieve(id)) ?? serverReport` for live rows.
379
380
  4. Add one Data Source endpoint that calls the existing service layer.
380
381
  5. Move one mutation button from `fetch('/api/reports/...')` to `ablo.weatherReports.update(...)`.
381
382
  6. Add an outbox/events path for writes that still happen outside Ablo.
@@ -507,8 +508,8 @@ them.
507
508
  | `retrieve({ id })` | Async read of one row from the server (await it). |
508
509
  | `list({ where })` | Async read of many rows from the server (await it). |
509
510
  | `get(id)` | Synchronous local read of one synced row (positional id; use in render). |
510
- | `getAll({ where })` | Synchronous local read of many synced rows. |
511
- | `getCount({ where })` | Synchronous local count of synced rows. |
511
+ | `local.list({ where })` | Synchronous local read of many synced rows. |
512
+ | `local.count({ where })` | Synchronous local count of synced rows. |
512
513
  | `create({ data, id? })` | Create through the model client. |
513
514
  | `update({ id, data, ...opts })` | Update through the model client. |
514
515
  | `delete({ id, ...opts })` | Delete through the model client. |
@@ -1,8 +1,10 @@
1
1
  # Interaction Model
2
2
 
3
- When a person, a server action, and an AI agent can all write to the same row,
4
- you need one write path that stops them from clobbering each other. Ablo gives
5
- you exactly one: load the row, claim it while you work, update it, and wait for
3
+ > The one write path every actor shares: load, claim, update, confirm.
4
+
5
+ When two agents, a server action, and a person can all write to the same row, you
6
+ need one write path that stops them from clobbering each other. Ablo gives you
7
+ exactly one: load the row, claim it while you work, update it, and wait for
6
8
  confirmation. This page walks through that path and the few primitives behind it.
7
9
 
8
10
  Here's the whole path in one block — claim a row, update it inside the claim, and
@@ -24,7 +26,7 @@ of clobbering.
24
26
  | Primitive | Plane | Purpose |
25
27
  |---|---|---|
26
28
  | `Schema` | State | Declares typed models the app and agents can read and write. |
27
- | `Model` | State | The generated `ablo.<model>` model. Use `retrieve`/`list` (async server reads), `get`/`getAll`/`getCount` (synchronous local reads), `create`, `update`, and `delete`. |
29
+ | `Model` | State | The generated `ablo.<model>` model. Use `retrieve`/`list` (async reads), `local.retrieve`/`local.list`/`local.count` (the same verbs, synchronous and local-only), `create`, `update`, and `delete`. |
28
30
  | `Claim` | Coordination | Who is working on a target. Taken via `ablo.<model>.claim({ id })` and read via `ablo.<model>.claim.state({ id })`. Ephemeral — never persisted. |
29
31
  | `Commit` | Protocol | The durable write underneath model updates. Most users do not call it directly. |
30
32
  | `Receipt` | Protocol | The lower-level durable result for custom runtimes. Schema writes use `wait: 'confirmed'`. |
package/docs/mcp.md CHANGED
@@ -1,38 +1,64 @@
1
1
  # Model Context Protocol
2
2
 
3
+ > Two MCP servers for two different jobs — one of them is a data plane, one is not.
4
+
3
5
  Ablo publishes **two** MCP servers for two different jobs. Don't confuse them:
4
6
 
5
7
  | Server | Purpose | Auth | Tools |
6
8
  |---|---|---|---|
7
- | **Coordination** (`@ablo/mcp`) | Let an agent safely read & mutate your application data | API key (`sk_…` / `rk_…`) | per-model `get` / `list` / `create` / `update` / `delete` / `claim` / `release` |
9
+ | **Coordination** (`@abloatai/mcp`) | Manage your Ablo the way the CLI does, and let an agent safely read & mutate application data | API key (`sk_…` / `rk_…`) | projects, schema, logs, usage — plus `get` / `list` / `create` / `update` / `delete` / `claim` / `release` over your rows |
8
10
  | **Integration-helper** (hosted `/api/mcp`) | Help an AI coding assistant write SDK integration code that compiles | none (public docs) | doc search, export surface, schema lint, scaffold |
9
11
 
10
- The coordination server **is the data plane** — it is how an agent changes
11
- state. The integration-helper server only serves docs, schema lint, and
12
- scaffolds; it does **not** read or write application data (there are no
12
+ The coordination server manages your account **and is the data plane** — it is
13
+ how an agent changes state. The integration-helper server only serves docs,
14
+ schema lint, and scaffolds; it does **not** read or write application data (there are no
13
15
  per-model data tools on it). Pick by what you're doing: shipping an agent that
14
16
  edits rows → coordination; teaching your IDE assistant the SDK → helper.
15
17
 
16
- ## Coordination server (`@ablo/mcp`)
18
+ ## Coordination server (`@abloatai/mcp`)
17
19
 
18
- The coordination server is the MCP projection of the model-scoped API
19
- (`/api/v1/models/...`) — the same surface as `ablo.<model>.create/update/claim` and
20
- the REST routes, rendered as tools. An agent connects with your API key and
21
- gets one safe loop: **claim → read → commit → release.**
20
+ The coordination server does two jobs: it manages your Ablo the way the `ablo`
21
+ CLI does, and it renders the model-scoped API (`/api/v1/models/...`) as tools
22
+ the same surface as `ablo.<model>.create/update/claim`. An agent connects with
23
+ your API key and gets one safe loop: **claim → read → commit → release.**
22
24
 
23
25
  Install over stdio; set your key in the host's MCP env:
24
26
 
25
27
  ```bash
26
- claude mcp add ablo -- npx -y @ablo/mcp
28
+ claude mcp add ablo -- npx -y @abloatai/mcp
27
29
  # env: ABLO_API_KEY=sk_… (ABLO_API_URL optional; defaults to the hosted API)
28
30
  ```
29
31
 
30
- Each tool mirrors an SDK verb, scoped to a model + id:
32
+ ### Managing your Ablo
33
+
34
+ | Tool | Mirrors | Does |
35
+ |---|---|---|
36
+ | `get_schema` | `ablo status` | the models this key can address, and its environment + project |
37
+ | `list_projects` | `ablo projects list` | the org's projects (needs `sk_`) |
38
+ | `create_project` | `ablo projects create` | create one (needs `sk_`) |
39
+ | `tail_logs` | `ablo logs` | recent commits and the actor behind each |
40
+ | `get_usage` | — | usage in daily buckets |
41
+
42
+ There are no key-management tools. A mint returns the plaintext once — only a
43
+ hash is kept — so no tool can hand it back later, and returning it at mint time
44
+ would write a live secret into the agent's context and the conversation
45
+ transcript, where it outlives any revocation. Listing and revoking will arrive
46
+ once a grant identifies the caller as a person rather than a key. Manage keys
47
+ with `ablo login` or the dashboard.
48
+
49
+ `ablo init`, `push`, `pull`, and `generate` have no tools: they read and write
50
+ files in your repo, which the server cannot see. Run those in a shell — then
51
+ call `get_schema` to see the result.
52
+
53
+ ### Reading and changing rows
54
+
55
+ Each tool mirrors an SDK verb, scoped to a model + id. Model names come from
56
+ `get_schema`:
31
57
 
32
58
  | Tool | Mirrors | Does |
33
59
  |---|---|---|
34
- | `get_model` | `ablo.<model>.get(id)` | read latest state + active claims |
35
- | `list_models` | `ablo.<model>.list({…})` | cursor-paginated list with filters |
60
+ | `get_model` | `ablo.<model>.local.retrieve(id)` | read latest state + active claims |
61
+ | `list_records` | `ablo.<model>.list({…})` | cursor-paginated list with filters |
36
62
  | `create_model` | `ablo.<model>.create({ data })` | guarded create |
37
63
  | `update_model` | `ablo.<model>.update({ id, … })` | guarded update |
38
64
  | `delete_model` | `ablo.<model>.delete({ id })` | guarded delete |
@@ -41,8 +67,7 @@ Each tool mirrors an SDK verb, scoped to a model + id:
41
67
 
42
68
  The agent-facing contract — the safe loop, the "derive idempotency keys from
43
69
  the business event" rule, and the error-code playbook — ships as a loadable
44
- skill at `@ablo/mcp/skill.md`. Lives in `packages/mcp/`
45
- (`createCoordinationMcpServer`, `src/tools.ts`).
70
+ skill at `@abloatai/mcp/skill.md`.
46
71
 
47
72
  ## Integration-helper server
48
73
 
@@ -57,7 +82,7 @@ server above, never here.
57
82
  > The `@abloatai/ablo` npm package itself bundles neither server — it has
58
83
  > no `@modelcontextprotocol/sdk` dependency. The helper is a feature of Ablo's
59
84
  > hosted app, mounted at `/api/mcp`; the coordination server is the separate
60
- > `@ablo/mcp` package.
85
+ > `@abloatai/mcp` package.
61
86
 
62
87
  ### Install
63
88
 
package/docs/migration.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Version History & Migration Guide
2
2
 
3
+ > Every breaking change and the edit it requires, newest first.
4
+
3
5
  The breaking-changes-first companion to the [Changelog](../CHANGELOG.md). The
4
6
  changelog tells the story of each release; this page tells you exactly what to
5
7
  change when you upgrade.
@@ -11,6 +13,8 @@ change when you upgrade.
11
13
 
12
14
  | Version | What changed | What to do |
13
15
  |---|---|---|
16
+ | **0.35.0** | Synchronous reads moved under `local`, mirroring the async verbs | `get(id)` → `local.retrieve(id)`; `getAll(options)` → `local.list(options)`; `getCount(options)` → `local.count(options)` |
17
+ | **0.35.0** | `causedByTaskId` write option + seven `turn_*` error codes removed | Delete the `causedByTaskId` argument from writes; a branch on `turn_validation_failed` was unreachable and can go with it |
14
18
  | **0.34.0** | Presence verb renamed `watch` → `join` | `ablo.<model>.watch(ids)` → `ablo.<model>.join(ids)`; `useWatch` → `useJoin`; the `WatchOptions` / `UseWatchOptions` / `UseWatchReturn` types → `JoinOptions` / `UseJoinOptions` / `UseJoinReturn`; error code `model_watch_not_configured` → `model_join_not_configured` |
15
19
  | **0.28.0** | Removed React placeholders that had no working runtime | `usePresence` → `usePeers` or `useJoin`; `useClaim` → `ablo.<model>.claim`; `SyncGroupProvider` / `useSyncGroup` → `useJoin({ scope })` |
16
20
  | **0.11.0** | Historical `intent` → `claim` rename | The hook renamed in that release was later removed in 0.28.0. Current code uses `ablo.<model>.claim` or `useJoin` |
@@ -27,6 +31,60 @@ change when you upgrade.
27
31
 
28
32
  ---
29
33
 
34
+ ## 0.35.0 — the synchronous reads move under `local`
35
+
36
+ ```diff
37
+ - const task = ablo.tasks.get(id);
38
+ - const open = ablo.tasks.getAll({ where: { status: 'open' } });
39
+ - const count = ablo.tasks.getCount({ where: { status: 'open' } });
40
+ + const task = ablo.tasks.local.retrieve(id);
41
+ + const open = ablo.tasks.local.list({ where: { status: 'open' } });
42
+ + const count = ablo.tasks.local.count({ where: { status: 'open' } });
43
+ ```
44
+
45
+ Options, return types, and reactivity inside `useAblo` selectors are unchanged.
46
+ Every verb now matches its asynchronous sibling, and `local` narrows the read to
47
+ what has already synced — which is what lets it return a value rather than a
48
+ promise.
49
+
50
+ `getAll` and `getCount` are distinctive enough to rename by search. `get` is not:
51
+ in most codebases it is outnumbered many times over by `Map.get` and
52
+ `headers.get`, and no search separates them. Upgrade the package first and let
53
+ the compiler name the sites — each one is a type error at exactly the call that
54
+ has to move.
55
+
56
+ ## 0.35.0 — `causedByTaskId` and the `turn_*` error codes removed
57
+
58
+ 0.9.2 retired the `turn` primitive but left one field standing: `causedByTaskId`
59
+ on the write options bag. It was never usable. The server validated it against a
60
+ task record that nothing in the system has ever created, so supplying it had the
61
+ whole batch rejected with `turn_validation_failed`, while leaving it null passed
62
+ straight through. The safe way to use the option was to not use it.
63
+
64
+ **Removed:** `MutationOptions.causedByTaskId`, the seven `turn_*` error codes
65
+ (`turn_validation_failed`, `turn_open_failed`, `turn_close_failed`,
66
+ `turn_not_found`, `turn_foreign_agent`, `parent_turn_not_found`,
67
+ `parent_turn_foreign_agent`), and the stored row's provenance slice
68
+ (`deltaProvenanceSchema` and the `DeltaProvenance` type). `syncDeltaRowSchema` is
69
+ now the core and attribution slices composed.
70
+
71
+ ```diff
72
+ - await ablo.documents.update({ id, data, causedByTaskId: turnId });
73
+ + await ablo.documents.update({ id, data });
74
+ ```
75
+
76
+ Attribution is unaffected. A delta still records the actor, the `onBehalfOf`
77
+ principal behind a delegated write, the capability that authorized it, and the
78
+ claim it was made under — which is what answers "who did this, and by what
79
+ right." On the wire the field was optional and nullable, so a client that still
80
+ sends it is accepted and ignored.
81
+
82
+ The `caused_by_task_id` column stays, for the reason 0.9.2 gave when it kept it:
83
+ the audit hash-chain signs its value into every row. Dropping it is a versioned
84
+ migration of its own.
85
+
86
+ ---
87
+
30
88
  ## 0.34.0 — presence verb renamed `watch` → `join`
31
89
 
32
90
  The model-level presence verb read like a data subscription but delivered
@@ -35,13 +93,13 @@ does. `ablo.<model>.join(ids, { ttl })` opens the participant handle
35
93
  (`.peers`, `.claims`, `await using` disposal); the returned `status` was
36
94
  already `'joined'`, and the layer beneath always called itself `join`, so the
37
95
  verb now matches. `onChange` remains the way to hear row *values* change, and
38
- `track` remains the durable read-dependency for actors.
96
+ `track` remains the durable premise for actors.
39
97
 
40
98
  ```ts
41
99
  // before
42
- await using room = await ablo.slides.watch(slideIds, { ttl: '5m' });
100
+ await using room = await ablo.documents.watch(documentIds, { ttl: '5m' });
43
101
  // after
44
- await using room = await ablo.slides.join(slideIds, { ttl: '5m' });
102
+ await using room = await ablo.documents.join(documentIds, { ttl: '5m' });
45
103
  ```
46
104
 
47
105
  The React hook follows: `useWatch({ scope })` → `useJoin({ scope })`. There is
@@ -148,7 +206,7 @@ distinct stores.
148
206
  server-side actors (agents, workers, serverless): the same `ablo.<model>` surface
149
207
  and `claim` coordination, but each call is one HTTP round-trip with identity on
150
208
  the Bearer credential — no websocket, no local synced pool. The return type
151
- narrows, so stateful-only APIs (`get` / `getAll` / `onChange`) become compile
209
+ narrows, so stateful-only APIs (the `local` reads, `onChange`) become compile
152
210
  errors instead of latent runtime gaps. Existing code keeps the default
153
211
  `'websocket'` transport, unchanged.
154
212
 
@@ -227,7 +285,7 @@ modifier are named siblings. Reactive local reads stay on the synchronous
227
285
  + await ablo.tasks.retrieve({ id })
228
286
 
229
287
  - useAblo((ablo) => ablo.tasks.retrieve(id)) ?? serverTask
230
- + useAblo((ablo) => ablo.tasks.get(id)) ?? serverTask
288
+ + useAblo((ablo) => ablo.tasks.local.retrieve(id)) ?? serverTask
231
289
  ```
232
290
 
233
291
  `claim` now returns a disposable handle instead of taking a callback. The handle
@@ -1,5 +1,7 @@
1
1
  # Operating on Your Database
2
2
 
3
+ > Which actions run freely, which to verify first, and which belong to a human.
4
+
3
5
  Ablo sits over your database as a coordination layer, not an owner. It reads
4
6
  your Postgres replication stream and routes each write through a claim-checked
5
7
  commit that lands in your own tables. It never runs DDL, never migrates, never
@@ -79,7 +81,7 @@ code question. The question that governs safety is *does removing this drop a
79
81
  real table on the next push* — and that one is answered against the database,
80
82
  not the codebase. Before removing a model that maps a live table, confirm the
81
83
  table is gone or empty and that your push path is additive; otherwise keep the
82
- model until the data is dealt with. A `load: 'manual'` mapping is often present
84
+ model until the data is dealt with. A `load: 'lazy'` mapping is often present
83
85
  precisely to hold a table in place, so treat its comment as load-bearing.
84
86
 
85
87
  ## The verification loop
package/docs/projects.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Projects
2
2
 
3
+ > One organization, many apps — each with its own schema, data planes, and keys.
4
+
3
5
  A **project** is the isolation unit inside your organization — the shape you
4
6
  know from Neon or Supabase. Each app you build gets its own project, and each
5
7
  project gets its own schema, its own sandbox/production data planes, and its
@@ -1,7 +1,9 @@
1
1
  # Quickstart
2
2
 
3
+ > Make your first coordinated write, on the Postgres you already have.
4
+
3
5
  Build with Ablo on **the Postgres you already have**. You declare a small Ablo
4
- schema for the models humans and agents edit together, connect Ablo to your
6
+ schema for the models your agents edit together, connect Ablo to your
5
7
  database (`ablo connect`), and read and write every one of those models through
6
8
  `ablo.<model>`. You write through Ablo; it lands the change in your Postgres and
7
9
  confirms it by tailing your write-ahead log (WAL). Your rows live in your database,
@@ -86,6 +88,22 @@ import type { Model } from '@abloatai/ablo/schema';
86
88
  type WeatherReport = Model<'weatherReports'>; // fully typed from YOUR schema
87
89
  ```
88
90
 
91
+ The same block is where you name the metadata your claims carry. Add a
92
+ `ClaimMeta` key and every `claim.state`, `claim.queue`, and held claim reads
93
+ `target.meta` as that shape:
94
+
95
+ ```ts
96
+ declare module '@abloatai/ablo' {
97
+ interface Register {
98
+ Schema: typeof schema;
99
+ ClaimMeta: { blocks: string[] };
100
+ }
101
+ }
102
+
103
+ const holder = ablo.weatherReports.claim.state({ id });
104
+ holder?.target.meta?.blocks.length; // typed, no guard
105
+ ```
106
+
89
107
  (The same `Register` binding types every hook and client — it's the
90
108
  TanStack-Router pattern: declare the source of truth once, everything
91
109
  infers from it.)
@@ -169,10 +187,9 @@ tables** — Ablo reads them, it does not create or migrate them:
169
187
  the tables with your own migration tool; Ablo syncs the subset of models you
170
188
  declared and reports the rest as "ignored / owned by you."
171
189
 
172
- > **Optional escape hatch:** if you have no tables yet and want Ablo to scaffold
173
- > them, `npx ablo migrate` can create your synced-model tables for you. This is
174
- > not the happy path connecting a real database is `ablo connect` (step 3), and
175
- > your own migrations stay in charge of your schema.
190
+ > **Starting from an empty database?** `npx ablo migrate` creates the tables
191
+ > your schema needs. Once they exist, your own migration tool stays in charge
192
+ > of themAblo adopts whatever shape you evolve.
176
193
 
177
194
  Nothing runs locally — there is no dev server to start. Your app talks to Ablo's
178
195
  hosted API; the rows live in your database.
package/docs/react.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # React
2
2
 
3
+ > Provider, hooks, and reactive reads for the interfaces people watch agent work arrive in.
4
+
3
5
  The React bindings for `@abloatai/ablo`. Use them when you want live
4
6
  data on the client without writing fetch + WebSocket plumbing yourself.
5
7
 
@@ -85,7 +87,7 @@ org / team / user map to what a participant can see.
85
87
  import { useAblo } from '@abloatai/ablo/react';
86
88
 
87
89
  export function ReportView({ report: serverReport }: { report: { id: string; location: string } }) {
88
- const report = useAblo((ablo) => ablo.weatherReports.get(serverReport.id)) ?? serverReport;
90
+ const report = useAblo((ablo) => ablo.weatherReports.local.retrieve(serverReport.id)) ?? serverReport;
89
91
  const active = useAblo((ablo) => ablo.weatherReports.claim.state({ id: serverReport.id }));
90
92
  const claimed = Boolean(active);
91
93
 
@@ -95,7 +97,7 @@ export function ReportView({ report: serverReport }: { report: { id: string; loc
95
97
 
96
98
  The hook:
97
99
 
98
- 1. Uses the same `ablo.<model>.get(id)` / `.getAll()` methods you'd call anywhere
100
+ 1. Uses the same `ablo.<model>.local.retrieve(id)` / `.local.list()` methods you'd call anywhere
99
101
  else in the SDK — the hook just makes them reactive.
100
102
  2. Tracks the model fields read by the selector and re-renders when confirmed
101
103
  deltas arrive.
@@ -110,14 +112,14 @@ effects, or writes:
110
112
  const abloClient = useAblo();
111
113
  ```
112
114
 
113
- Prefer selector reads like `useAblo((ablo) => ablo.<model>.get(id))`. Older hooks
115
+ Prefer selector reads like `useAblo((ablo) => ablo.<model>.local.retrieve(id))`. Older hooks
114
116
  also accept a string model name; prefer the selector form shown above.
115
117
 
116
118
  For collections, keep the selector on the model client too:
117
119
 
118
120
  ```tsx
119
121
  const reports = useAblo((ablo) =>
120
- ablo.weatherReports.getAll({
122
+ ablo.weatherReports.local.list({
121
123
  where: { projectId },
122
124
  filter: (report) => report.status !== 'ready',
123
125
  state: 'live',
@@ -135,7 +137,7 @@ Use `retrieve` in Server Components when the row may not be in the local pool
135
137
  yet — it hydrates from the local store and the server, and returns a Promise, so
136
138
  `await` it. (Server reads come in two shapes: `retrieve({ id })` for one row and
137
139
  `list({ where })` for many; both are async. The synchronous local reads are
138
- `get`/`getAll`/`getCount`, used in render below.)
140
+ the `local` reads, used in render below.)
139
141
 
140
142
  ## Writes
141
143
 
@@ -191,11 +193,11 @@ write interest in it.
191
193
 
192
194
  import { useJoin } from '@abloatai/ablo/react';
193
195
 
194
- export function DeckPresence({ deckId }: { deckId: string }) {
196
+ export function DeckPresence({ workspaceId }: { workspaceId: string }) {
195
197
  const { peers, claims, status } = useJoin({
196
- scope: { slideDecks: deckId },
198
+ scope: { slideDecks: workspaceId },
197
199
  claim: true, // I intend to write — pin the scope + let peers observe the claim
198
- hydrate: true, // backfill the deck's current rows if not already loaded
200
+ hydrate: true, // backfill the workspace's current rows if not already loaded
199
201
  });
200
202
 
201
203
  if (status !== 'joined') return <span>connecting…</span>;
@@ -230,8 +232,8 @@ connection is subscribed to.
230
232
 
231
233
  import { usePeers } from '@abloatai/ablo/react';
232
234
 
233
- export function CursorBroadcaster({ deckId }: { deckId: string }) {
234
- const peers = usePeers({ slideDecks: deckId });
235
+ export function CursorBroadcaster({ workspaceId }: { workspaceId: string }) {
236
+ const peers = usePeers({ slideDecks: workspaceId });
235
237
  const alone = !peers.some((p) => p.participantKind === 'user');
236
238
  // suppress live-cursor broadcasts while alone
237
239
  }
@@ -1,5 +1,7 @@
1
1
  # Schema Contract
2
2
 
3
+ > One schema becomes typed clients, agent writes, interface reads, and the hosted push.
4
+
3
5
  Ablo's schema is the integration contract. Define it once, pass it to `Ablo(...)`,
4
6
  and every actor gets the same typed model surface:
5
7
 
@@ -10,7 +12,7 @@ defineSchema(...) -> ablo.<model>.create/retrieve/update/claim(...)
10
12
  That one object drives:
11
13
 
12
14
  - typed model clients in trusted server runtimes,
13
- - React selectors through `useAblo((ablo) => ablo.<model>.get(id))`,
15
+ - React selectors through `useAblo((ablo) => ablo.<model>.local.retrieve(id))`,
14
16
  - agent and background-worker writes,
15
17
  - Data Source request/response shape when your database stays canonical,
16
18
  - hosted schema push, migration planning, and schema-version gating.
@@ -75,8 +77,8 @@ const ready = await ablo.weatherReports.list({ where: { status: 'ready' } });
75
77
  Use synchronous local reads in render after data has synced:
76
78
 
77
79
  ```ts
78
- const report = ablo.weatherReports.get(reportId);
79
- const pending = ablo.weatherReports.getAll({ where: { status: 'pending' } });
80
+ const report = ablo.weatherReports.local.retrieve(reportId);
81
+ const pending = ablo.weatherReports.local.list({ where: { status: 'pending' } });
80
82
  ```
81
83
 
82
84
  Use model writes for every actor:
@@ -0,0 +1,108 @@
1
+ # Session Settings
2
+
3
+ > Point your row-level-security policies at Ablo's writes, by naming the Postgres session settings they already read.
4
+
5
+ Ablo writes your rows through a scoped role with `row_security` on and
6
+ `NOBYPASSRLS` set, so your policies govern its writes the same way they govern
7
+ your own application's. They only govern well if they can see who the write is
8
+ for. Before each write, Ablo sets its own identity context on the transaction —
9
+ and if your policies read settings under names you chose, `sessionSettings` maps
10
+ one to the other:
11
+
12
+ ```ts
13
+ import { defineSchema, model, z } from '@abloatai/ablo/schema';
14
+
15
+ export const schema = defineSchema(
16
+ {
17
+ invoices: model({
18
+ total: z.number(),
19
+ reference: z.string(),
20
+ }),
21
+ },
22
+ {
23
+ sessionSettings: { 'app.current_org': 'orgId' },
24
+ },
25
+ );
26
+ ```
27
+
28
+ A policy written against `current_setting('app.current_org')` now applies to
29
+ Ablo's write, unchanged:
30
+
31
+ ```sql
32
+ CREATE POLICY tenant_isolation ON invoices
33
+ USING (organization_id = current_setting('app.current_org', true));
34
+ ```
35
+
36
+ The key is the setting name **your** policies read. The value names which piece
37
+ of Ablo's authenticated identity fills it.
38
+
39
+ ## What Ablo sets on its own
40
+
41
+ Every direct write runs inside a transaction that begins by setting this
42
+ context, whether or not you map anything:
43
+
44
+ | Setting | Carries |
45
+ | --- | --- |
46
+ | `app.current_org_id` | The organization the credential acts for |
47
+ | `app.current_project_id` | The project |
48
+ | `app.current_environment` | The environment |
49
+ | `app.current_sandbox_id` | The sandbox, when the write is in one |
50
+ | `app.current_participant_id` | The participant making the write |
51
+ | `app.current_participant_kind` | Whether that participant is a person, an agent, or the system |
52
+ | `app.current_user_id` | The person on whose behalf the write is made |
53
+
54
+ If your policies read these names directly, you need no mapping at all — this
55
+ page is for the case where they read different ones.
56
+
57
+ `app.current_user_id` is worth reading twice, because it has three states rather
58
+ than two. It carries a person's id when a person is behind the write. It carries
59
+ `*` when a backend credential is acting as the organization itself, which is the
60
+ authority a server-side key holds. And it carries the empty string when no
61
+ identity could be established — written explicitly rather than left alone, so a
62
+ policy on a pooled connection reads absence as absence and denies, instead of
63
+ inheriting whatever the previous transaction left behind.
64
+
65
+ ## What a mapping may name
66
+
67
+ The value side is a closed set, and every member is resolved by Ablo from the
68
+ authenticated key and the plane:
69
+
70
+ `orgId` · `projectId` · `environment` · `sandboxId` · `participantId` ·
71
+ `participantKind`
72
+
73
+ Because none of them come from the caller, a mapping can forward the tenant
74
+ identity Ablo already trusts, but cannot widen what a writer sees. A setting name
75
+ takes exactly one source — the name is the key — so naming the same setting twice
76
+ is unrepresentable rather than something to resolve later.
77
+
78
+ ## What a mapping may not name
79
+
80
+ The settings in the table above, along with `row_security`, `search_path`,
81
+ `statement_timeout`, and `lock_timeout`, are reserved. `defineSchema` rejects a
82
+ mapping onto any of them, and the engine refuses one at write time too.
83
+
84
+ The reason is worth stating plainly: those settings are how Ablo bounds its own
85
+ write. A schema that could reassign them could relax the scoping under which
86
+ Ablo writes, which would put the boundary inside the thing being bounded. Point
87
+ your policies at a name you own — `app.current_org` rather than
88
+ `app.current_org_id` — and map that.
89
+
90
+ ## Reads served from the log
91
+
92
+ One arrangement cannot honour a policy that names a person. When a plane is
93
+ served from its retained log rather than from its tables, every row carries the
94
+ organization and the project, but not the owner — so a rule about who owns a row
95
+ has nothing to act on.
96
+
97
+ Rather than fold those rows and return a plausible answer, such a read is
98
+ declined whole with `user_scope_not_enforced`: a member reading a colleague's
99
+ private records would otherwise be indistinguishable from a member reading their
100
+ own. Reads made by a credential acting for the organization are unaffected, as is
101
+ every plane served from its tables.
102
+
103
+ ## Related
104
+
105
+ - [Data Sources](./data-sources.md) — the writer role's privileges, and what it
106
+ can and cannot do to your database.
107
+ - [Operating on Your Database](./operating-on-your-database.md) — which actions
108
+ are read-only, which are reversible, and which belong to a human.
package/docs/sessions.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Sessions
2
2
 
3
+ > Short-lived scoped credentials your backend mints for a browser or an agent.
4
+
3
5
  A **session** is a short-lived credential your backend mints with its `sk_` and
4
6
  hands to one actor — a signed-in **person's browser** or a scoped **agent**. It's
5
7
  the same primitive in both cases (backend-minted, short-lived, scoped); the only
@@ -16,7 +18,7 @@ const userSession = await ablo.sessions.create({
16
18
  // A scoped agent session — gated to exactly the operations you name.
17
19
  const agentSession = await ablo.sessions.create({
18
20
  agent: { id: 'agent:task-writer' },
19
- can: { Task: ['read', 'update'], Deck: ['read'] },
21
+ can: { Task: ['read', 'update'], Workspace: ['read'] },
20
22
  });
21
23
  ```
22
24
 
package/docs/webhooks.md CHANGED
@@ -1,7 +1,9 @@
1
1
  # Webhooks
2
2
 
3
+ > Stream the committed transaction log to your own systems as signed events.
4
+
3
5
  Ablo keeps an ordered transaction log of every committed change and coordinates
4
- the writers — people and agents — that produce it. Your rows live in your own
6
+ the writers — agents, and the people alongside them — that produce it. Your rows live in your own
5
7
  database; Ablo holds only the log. **Webhooks stream that log to your systems as
6
8
  signed events:** every committed change is POSTed to an endpoint in your app, and
7
9
  your handler decides what to do with it.