@abloatai/ablo 0.7.0 → 0.9.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/CHANGELOG.md +72 -1
- package/README.md +80 -66
- package/dist/BaseSyncedStore.d.ts +73 -0
- package/dist/BaseSyncedStore.js +179 -5
- package/dist/Model.d.ts +42 -0
- package/dist/Model.js +103 -44
- package/dist/SyncEngineContext.d.ts +2 -1
- package/dist/SyncEngineContext.js +5 -3
- package/dist/agent/session.js +6 -5
- package/dist/ai-sdk/coordination-context.js +4 -0
- package/dist/ai-sdk/index.d.ts +56 -47
- package/dist/ai-sdk/index.js +56 -47
- package/dist/ai-sdk/intent-broadcast.d.ts +5 -0
- package/dist/ai-sdk/intent-broadcast.js +11 -4
- package/dist/ai-sdk/wrap.d.ts +14 -11
- package/dist/ai-sdk/wrap.js +11 -13
- package/dist/auth/credentialSource.d.ts +34 -0
- package/dist/auth/credentialSource.js +63 -0
- package/dist/auth/index.d.ts +2 -22
- package/dist/auth/index.js +26 -36
- package/dist/auth/schemas.d.ts +35 -0
- package/dist/auth/schemas.js +53 -0
- package/dist/client/Ablo.d.ts +259 -33
- package/dist/client/Ablo.js +276 -73
- package/dist/client/ApiClient.d.ts +52 -4
- package/dist/client/ApiClient.js +236 -66
- package/dist/client/auth.d.ts +21 -2
- package/dist/client/auth.js +77 -5
- package/dist/client/createInternalComponents.d.ts +2 -0
- package/dist/client/createInternalComponents.js +8 -1
- package/dist/client/createModelProxy.d.ts +187 -79
- package/dist/client/createModelProxy.js +203 -68
- package/dist/client/httpClient.d.ts +71 -0
- package/dist/client/httpClient.js +69 -0
- package/dist/client/identity.d.ts +2 -6
- package/dist/client/identity.js +63 -11
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.js +1 -0
- package/dist/client/registerDataSource.d.ts +19 -0
- package/dist/client/registerDataSource.js +59 -0
- package/dist/client/validateAbloOptions.d.ts +2 -1
- package/dist/client/validateAbloOptions.js +8 -7
- package/dist/core/DatabaseManager.js +30 -2
- package/dist/core/openIDBWithTimeout.d.ts +36 -0
- package/dist/core/openIDBWithTimeout.js +88 -1
- package/dist/errorCodes.d.ts +92 -1
- package/dist/errorCodes.js +139 -7
- package/dist/errors.d.ts +54 -3
- package/dist/errors.js +192 -44
- package/dist/index.d.ts +23 -10
- package/dist/index.js +21 -8
- package/dist/keys/index.d.ts +76 -0
- package/dist/keys/index.js +171 -0
- package/dist/mutators/UndoManager.d.ts +86 -50
- package/dist/mutators/UndoManager.js +129 -22
- package/dist/mutators/inverseOp.d.ts +129 -0
- package/dist/mutators/inverseOp.js +74 -0
- package/dist/mutators/readerActions.d.ts +1 -1
- package/dist/mutators/undoApply.d.ts +42 -0
- package/dist/mutators/undoApply.js +143 -0
- package/dist/query/client.d.ts +10 -9
- package/dist/query/client.js +22 -14
- package/dist/react/AbloProvider.d.ts +23 -101
- package/dist/react/AbloProvider.js +61 -103
- package/dist/react/ClientSideSuspense.d.ts +1 -1
- package/dist/react/DefaultFallback.d.ts +1 -1
- package/dist/react/SyncGroupProvider.d.ts +1 -1
- package/dist/react/index.d.ts +3 -2
- package/dist/react/index.js +3 -2
- package/dist/react/useAblo.d.ts +4 -4
- package/dist/react/useAblo.js +10 -5
- package/dist/react/useCurrentUserId.d.ts +1 -1
- package/dist/react/useCurrentUserId.js +1 -1
- package/dist/react/useMutators.js +19 -12
- package/dist/react/useReactive.js +16 -3
- package/dist/schema/ddl.d.ts +26 -3
- package/dist/schema/ddl.js +152 -4
- package/dist/schema/index.d.ts +4 -0
- package/dist/schema/index.js +12 -0
- package/dist/schema/model.d.ts +11 -0
- package/dist/schema/model.js +2 -0
- package/dist/schema/openapi.d.ts +28 -0
- package/dist/schema/openapi.js +118 -0
- package/dist/schema/plane.d.ts +23 -0
- package/dist/schema/plane.js +19 -0
- package/dist/schema/relation.d.ts +20 -0
- package/dist/schema/serialize.d.ts +7 -3
- package/dist/schema/serialize.js +6 -2
- package/dist/schema/sync-delta-row.d.ts +157 -0
- package/dist/schema/sync-delta-row.js +102 -0
- package/dist/schema/sync-delta-wire.d.ts +180 -0
- package/dist/schema/sync-delta-wire.js +102 -0
- package/dist/server/adapter.d.ts +156 -0
- package/dist/server/adapter.js +19 -0
- package/dist/server/commit.d.ts +82 -0
- package/dist/server/commit.js +1 -0
- package/dist/server/index.d.ts +14 -0
- package/dist/server/index.js +1 -0
- package/dist/server/next.d.ts +51 -0
- package/dist/server/next.js +47 -0
- package/dist/server/read-config.d.ts +60 -0
- package/dist/server/read-config.js +8 -0
- package/dist/server/storage-mode.d.ts +17 -0
- package/dist/server/storage-mode.js +12 -0
- package/dist/source/adapter.d.ts +59 -0
- package/dist/source/adapter.js +19 -0
- package/dist/source/adapters/drizzle.d.ts +34 -0
- package/dist/source/adapters/drizzle.js +147 -0
- package/dist/source/adapters/memory.d.ts +12 -0
- package/dist/source/adapters/memory.js +114 -0
- package/dist/source/adapters/prisma.d.ts +57 -0
- package/dist/source/adapters/prisma.js +199 -0
- package/dist/source/conformance.d.ts +32 -0
- package/dist/source/conformance.js +134 -0
- package/dist/source/contract.d.ts +143 -0
- package/dist/source/contract.js +98 -0
- package/dist/source/index.d.ts +61 -10
- package/dist/source/index.js +98 -0
- package/dist/source/next.d.ts +33 -0
- package/dist/source/next.js +26 -0
- package/dist/sync/BootstrapHelper.d.ts +10 -0
- package/dist/sync/BootstrapHelper.js +56 -42
- package/dist/sync/ConnectionManager.d.ts +57 -1
- package/dist/sync/ConnectionManager.js +186 -11
- package/dist/sync/HydrationCoordinator.d.ts +93 -17
- package/dist/sync/HydrationCoordinator.js +241 -41
- package/dist/sync/NetworkProbe.d.ts +60 -18
- package/dist/sync/NetworkProbe.js +121 -23
- package/dist/sync/SyncWebSocket.d.ts +45 -70
- package/dist/sync/SyncWebSocket.js +113 -89
- package/dist/sync/createIntentStream.js +10 -1
- package/dist/sync/participants.js +5 -2
- package/dist/transactions/TransactionQueue.js +13 -1
- package/dist/types/streams.d.ts +9 -0
- package/dist/utils/mobx-setup.js +1 -0
- package/dist/webhooks/events.d.ts +38 -0
- package/dist/webhooks/events.js +40 -0
- package/dist/webhooks/index.d.ts +10 -0
- package/dist/webhooks/index.js +10 -0
- package/dist/wire/errorEnvelope.d.ts +34 -0
- package/dist/wire/errorEnvelope.js +86 -0
- package/dist/wire/frames.d.ts +119 -0
- package/dist/wire/frames.js +1 -0
- package/dist/wire/index.d.ts +24 -0
- package/dist/wire/index.js +21 -0
- package/dist/wire/listEnvelope.d.ts +45 -0
- package/dist/wire/listEnvelope.js +17 -0
- package/docs/api-keys.md +5 -5
- package/docs/api.md +125 -65
- package/docs/audit.md +16 -9
- package/docs/cli.md +57 -47
- package/docs/client-behavior.md +54 -40
- package/docs/coordination.md +66 -80
- package/docs/data-sources.md +56 -34
- package/docs/examples/agent-human.md +74 -28
- package/docs/examples/ai-sdk-tool.md +29 -22
- package/docs/examples/existing-python-backend.md +41 -26
- package/docs/examples/nextjs.md +32 -17
- package/docs/examples/scoped-agent.md +43 -28
- package/docs/examples/server-agent.md +40 -15
- package/docs/guarantees.md +38 -27
- package/docs/identity.md +65 -59
- package/docs/index.md +30 -19
- package/docs/integration-guide.md +78 -78
- package/docs/interaction-model.md +43 -35
- package/docs/mcp/claude-code.md +11 -19
- package/docs/mcp/cursor.md +7 -25
- package/docs/mcp/windsurf.md +7 -20
- package/docs/mcp.md +103 -26
- package/docs/quickstart.md +63 -61
- package/docs/react.md +24 -16
- package/docs/roadmap.md +13 -13
- package/docs/schema-contract.md +111 -0
- package/docs/the-loop.md +21 -0
- package/examples/README.md +8 -4
- package/examples/data-source/README.md +10 -7
- package/examples/data-source/customer-server.ts +27 -25
- package/examples/data-source/run.ts +4 -3
- package/examples/quickstart.ts +1 -1
- package/llms.txt +55 -21
- package/package.json +48 -3
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical Zod description of the `sync_deltas` STORAGE ROW, decomposed by the
|
|
3
|
+
* subsystem it belongs to and the database plane it lives in.
|
|
4
|
+
*
|
|
5
|
+
* `sync_deltas` fuses five control-plane subsystems onto one denormalized row
|
|
6
|
+
* (see `docs/plans/sync-delta-zod-decomposition.md`). This module is **P0** of
|
|
7
|
+
* that decomposition: it DESCRIBES the existing columns as Zod schemas — no DB
|
|
8
|
+
* change, no rewiring — so the subsystem + plane boundaries become explicit and
|
|
9
|
+
* type-enforced:
|
|
10
|
+
*
|
|
11
|
+
* - {@link syncDeltaCoreSchema} — the SYNC-PROTOCOL slice. `tenant` plane:
|
|
12
|
+
* the only part that must be written
|
|
13
|
+
* atomically with the app row, and the shape
|
|
14
|
+
* a BYO outbox marker carries (the portable
|
|
15
|
+
* slice).
|
|
16
|
+
* - {@link deltaAttributionSchema} — who / on whose authority. `control` plane.
|
|
17
|
+
* - {@link deltaProvenanceSchema} — which AI task caused it. `control` plane.
|
|
18
|
+
*
|
|
19
|
+
* {@link syncDeltaRowSchema} is the full stored row (core ∪ attribution ∪
|
|
20
|
+
* provenance). {@link DELTA_PLANES} declares each slice's plane so provisioning
|
|
21
|
+
* (P1) can derive "what a customer DB gets" from the schema, not hand-code it.
|
|
22
|
+
*
|
|
23
|
+
* Distinct from the WIRE `SyncDelta` (`sync/SyncWebSocket.ts`, client-facing) and
|
|
24
|
+
* `SourceDelta` (`source/index.ts`, source-mode input) — those are projections of
|
|
25
|
+
* this row. Field names mirror those + `AuditChainRow` (`@ablo/audit-chain`).
|
|
26
|
+
*
|
|
27
|
+
* Monorepo is on Zod v4 — `.extend(...).shape` (not deprecated `.merge`).
|
|
28
|
+
*/
|
|
29
|
+
import { z } from 'zod';
|
|
30
|
+
/** `participant_kind` */
|
|
31
|
+
export declare const participantKindSchema: z.ZodEnum<{
|
|
32
|
+
user: "user";
|
|
33
|
+
agent: "agent";
|
|
34
|
+
system: "system";
|
|
35
|
+
}>;
|
|
36
|
+
export type ParticipantKind = z.infer<typeof participantKindSchema>;
|
|
37
|
+
/** `confirmation_state` */
|
|
38
|
+
export declare const confirmationStateSchema: z.ZodEnum<{
|
|
39
|
+
auto: "auto";
|
|
40
|
+
previewed: "previewed";
|
|
41
|
+
approved: "approved";
|
|
42
|
+
required_human_approval: "required_human_approval";
|
|
43
|
+
auto_historical: "auto_historical";
|
|
44
|
+
}>;
|
|
45
|
+
export type ConfirmationState = z.infer<typeof confirmationStateSchema>;
|
|
46
|
+
/** `backfill_provenance` */
|
|
47
|
+
export declare const backfillProvenanceSchema: z.ZodEnum<{
|
|
48
|
+
unknown: "unknown";
|
|
49
|
+
exact: "exact";
|
|
50
|
+
inferred: "inferred";
|
|
51
|
+
}>;
|
|
52
|
+
export type BackfillProvenance = z.infer<typeof backfillProvenanceSchema>;
|
|
53
|
+
/**
|
|
54
|
+
* Everything a client needs to materialize the change, plus the tenant key. The
|
|
55
|
+
* portable slice: the only part written atomically with the app row, and the
|
|
56
|
+
* shape a BYO outbox marker carries. `id` / `createdAt` / `syncGroups` are
|
|
57
|
+
* control-plane-assigned at enrich/append time, so they're optional here (an
|
|
58
|
+
* outbox marker doesn't have them yet).
|
|
59
|
+
*/
|
|
60
|
+
export declare const syncDeltaCoreSchema: z.ZodObject<{
|
|
61
|
+
id: z.ZodOptional<z.ZodUnion<readonly [z.ZodBigInt, z.ZodNumber]>>;
|
|
62
|
+
actionType: z.ZodString;
|
|
63
|
+
modelName: z.ZodString;
|
|
64
|
+
modelId: z.ZodString;
|
|
65
|
+
data: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
66
|
+
previousData: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
67
|
+
syncGroups: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
68
|
+
organizationId: z.ZodNullable<z.ZodString>;
|
|
69
|
+
createdAt: z.ZodOptional<z.ZodString>;
|
|
70
|
+
transactionId: z.ZodNullable<z.ZodString>;
|
|
71
|
+
}, z.core.$strip>;
|
|
72
|
+
export type SyncDeltaCore = z.infer<typeof syncDeltaCoreSchema>;
|
|
73
|
+
export declare const deltaAttributionSchema: z.ZodObject<{
|
|
74
|
+
createdBy: z.ZodNullable<z.ZodString>;
|
|
75
|
+
actorId: z.ZodNullable<z.ZodString>;
|
|
76
|
+
actorKind: z.ZodNullable<z.ZodEnum<{
|
|
77
|
+
user: "user";
|
|
78
|
+
agent: "agent";
|
|
79
|
+
system: "system";
|
|
80
|
+
}>>;
|
|
81
|
+
onBehalfOfId: z.ZodNullable<z.ZodString>;
|
|
82
|
+
onBehalfOfKind: z.ZodNullable<z.ZodEnum<{
|
|
83
|
+
user: "user";
|
|
84
|
+
agent: "agent";
|
|
85
|
+
system: "system";
|
|
86
|
+
}>>;
|
|
87
|
+
capabilityId: z.ZodNullable<z.ZodString>;
|
|
88
|
+
confirmationState: z.ZodNullable<z.ZodEnum<{
|
|
89
|
+
auto: "auto";
|
|
90
|
+
previewed: "previewed";
|
|
91
|
+
approved: "approved";
|
|
92
|
+
required_human_approval: "required_human_approval";
|
|
93
|
+
auto_historical: "auto_historical";
|
|
94
|
+
}>>;
|
|
95
|
+
backfillProvenance: z.ZodNullable<z.ZodEnum<{
|
|
96
|
+
unknown: "unknown";
|
|
97
|
+
exact: "exact";
|
|
98
|
+
inferred: "inferred";
|
|
99
|
+
}>>;
|
|
100
|
+
}, z.core.$strip>;
|
|
101
|
+
export type DeltaAttribution = z.infer<typeof deltaAttributionSchema>;
|
|
102
|
+
export declare const deltaProvenanceSchema: z.ZodObject<{
|
|
103
|
+
causedByTaskId: z.ZodNullable<z.ZodString>;
|
|
104
|
+
}, z.core.$strip>;
|
|
105
|
+
export type DeltaProvenance = z.infer<typeof deltaProvenanceSchema>;
|
|
106
|
+
/** The complete `sync_deltas` row as stored today (core ∪ attribution ∪ provenance). */
|
|
107
|
+
export declare const syncDeltaRowSchema: z.ZodObject<{
|
|
108
|
+
id: z.ZodOptional<z.ZodUnion<readonly [z.ZodBigInt, z.ZodNumber]>>;
|
|
109
|
+
actionType: z.ZodString;
|
|
110
|
+
modelName: z.ZodString;
|
|
111
|
+
modelId: z.ZodString;
|
|
112
|
+
data: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
113
|
+
previousData: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
114
|
+
syncGroups: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
115
|
+
organizationId: z.ZodNullable<z.ZodString>;
|
|
116
|
+
createdAt: z.ZodOptional<z.ZodString>;
|
|
117
|
+
transactionId: z.ZodNullable<z.ZodString>;
|
|
118
|
+
createdBy: z.ZodNullable<z.ZodString>;
|
|
119
|
+
actorId: z.ZodNullable<z.ZodString>;
|
|
120
|
+
actorKind: z.ZodNullable<z.ZodEnum<{
|
|
121
|
+
user: "user";
|
|
122
|
+
agent: "agent";
|
|
123
|
+
system: "system";
|
|
124
|
+
}>>;
|
|
125
|
+
onBehalfOfId: z.ZodNullable<z.ZodString>;
|
|
126
|
+
onBehalfOfKind: z.ZodNullable<z.ZodEnum<{
|
|
127
|
+
user: "user";
|
|
128
|
+
agent: "agent";
|
|
129
|
+
system: "system";
|
|
130
|
+
}>>;
|
|
131
|
+
capabilityId: z.ZodNullable<z.ZodString>;
|
|
132
|
+
confirmationState: z.ZodNullable<z.ZodEnum<{
|
|
133
|
+
auto: "auto";
|
|
134
|
+
previewed: "previewed";
|
|
135
|
+
approved: "approved";
|
|
136
|
+
required_human_approval: "required_human_approval";
|
|
137
|
+
auto_historical: "auto_historical";
|
|
138
|
+
}>>;
|
|
139
|
+
backfillProvenance: z.ZodNullable<z.ZodEnum<{
|
|
140
|
+
unknown: "unknown";
|
|
141
|
+
exact: "exact";
|
|
142
|
+
inferred: "inferred";
|
|
143
|
+
}>>;
|
|
144
|
+
causedByTaskId: z.ZodNullable<z.ZodString>;
|
|
145
|
+
}, z.core.$strip>;
|
|
146
|
+
export type SyncDeltaRow = z.infer<typeof syncDeltaRowSchema>;
|
|
147
|
+
/**
|
|
148
|
+
* Each slice's database plane. The durable answer to "what does a BYO customer DB
|
|
149
|
+
* get?" — only `tenant`-plane slices. Provisioning (P1) reads this instead of
|
|
150
|
+
* hand-coding the boundary; the BYO outbox writes the `tenant` slice and the
|
|
151
|
+
* relay enriches the `control` slices in Ablo's own database.
|
|
152
|
+
*/
|
|
153
|
+
export declare const DELTA_PLANES: {
|
|
154
|
+
readonly core: "tenant";
|
|
155
|
+
readonly attribution: "control";
|
|
156
|
+
readonly provenance: "control";
|
|
157
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical Zod description of the `sync_deltas` STORAGE ROW, decomposed by the
|
|
3
|
+
* subsystem it belongs to and the database plane it lives in.
|
|
4
|
+
*
|
|
5
|
+
* `sync_deltas` fuses five control-plane subsystems onto one denormalized row
|
|
6
|
+
* (see `docs/plans/sync-delta-zod-decomposition.md`). This module is **P0** of
|
|
7
|
+
* that decomposition: it DESCRIBES the existing columns as Zod schemas — no DB
|
|
8
|
+
* change, no rewiring — so the subsystem + plane boundaries become explicit and
|
|
9
|
+
* type-enforced:
|
|
10
|
+
*
|
|
11
|
+
* - {@link syncDeltaCoreSchema} — the SYNC-PROTOCOL slice. `tenant` plane:
|
|
12
|
+
* the only part that must be written
|
|
13
|
+
* atomically with the app row, and the shape
|
|
14
|
+
* a BYO outbox marker carries (the portable
|
|
15
|
+
* slice).
|
|
16
|
+
* - {@link deltaAttributionSchema} — who / on whose authority. `control` plane.
|
|
17
|
+
* - {@link deltaProvenanceSchema} — which AI task caused it. `control` plane.
|
|
18
|
+
*
|
|
19
|
+
* {@link syncDeltaRowSchema} is the full stored row (core ∪ attribution ∪
|
|
20
|
+
* provenance). {@link DELTA_PLANES} declares each slice's plane so provisioning
|
|
21
|
+
* (P1) can derive "what a customer DB gets" from the schema, not hand-code it.
|
|
22
|
+
*
|
|
23
|
+
* Distinct from the WIRE `SyncDelta` (`sync/SyncWebSocket.ts`, client-facing) and
|
|
24
|
+
* `SourceDelta` (`source/index.ts`, source-mode input) — those are projections of
|
|
25
|
+
* this row. Field names mirror those + `AuditChainRow` (`@ablo/audit-chain`).
|
|
26
|
+
*
|
|
27
|
+
* Monorepo is on Zod v4 — `.extend(...).shape` (not deprecated `.merge`).
|
|
28
|
+
*/
|
|
29
|
+
import { z } from 'zod';
|
|
30
|
+
// ── Enums (mirror the Postgres enums; @@map name in the comment) ──────────────
|
|
31
|
+
/** `participant_kind` */
|
|
32
|
+
export const participantKindSchema = z.enum(['user', 'agent', 'system']);
|
|
33
|
+
/** `confirmation_state` */
|
|
34
|
+
export const confirmationStateSchema = z.enum([
|
|
35
|
+
'auto',
|
|
36
|
+
'previewed',
|
|
37
|
+
'approved',
|
|
38
|
+
'required_human_approval',
|
|
39
|
+
'auto_historical',
|
|
40
|
+
]);
|
|
41
|
+
/** `backfill_provenance` */
|
|
42
|
+
export const backfillProvenanceSchema = z.enum(['exact', 'inferred', 'unknown']);
|
|
43
|
+
/** A delta payload: the full post-mutation row (or null for deletes). */
|
|
44
|
+
const deltaDataSchema = z.record(z.string(), z.unknown()).nullable();
|
|
45
|
+
// ── Core — `tenant` plane (the sync-protocol slice) ───────────────────────────
|
|
46
|
+
/**
|
|
47
|
+
* Everything a client needs to materialize the change, plus the tenant key. The
|
|
48
|
+
* portable slice: the only part written atomically with the app row, and the
|
|
49
|
+
* shape a BYO outbox marker carries. `id` / `createdAt` / `syncGroups` are
|
|
50
|
+
* control-plane-assigned at enrich/append time, so they're optional here (an
|
|
51
|
+
* outbox marker doesn't have them yet).
|
|
52
|
+
*/
|
|
53
|
+
export const syncDeltaCoreSchema = z.object({
|
|
54
|
+
/** Monotonic sync id; assigned control-plane on append (absent on a marker). */
|
|
55
|
+
id: z.union([z.bigint(), z.number()]).optional(),
|
|
56
|
+
/** `action_type` — single char: `I` | `U` | `D`. */
|
|
57
|
+
actionType: z.string().min(1).max(1),
|
|
58
|
+
modelName: z.string().min(1),
|
|
59
|
+
modelId: z.string().min(1),
|
|
60
|
+
data: deltaDataSchema,
|
|
61
|
+
previousData: deltaDataSchema.optional(),
|
|
62
|
+
/** Sync-group routing keys; computed control-plane (`buildDeltaSyncGroups`). */
|
|
63
|
+
syncGroups: z.array(z.string()).optional(),
|
|
64
|
+
/** The TRUSTED committing org — the coarse tenant-isolation boundary. */
|
|
65
|
+
organizationId: z.string().nullable(),
|
|
66
|
+
/** ISO timestamp; control-plane-assigned at append. */
|
|
67
|
+
createdAt: z.string().optional(),
|
|
68
|
+
transactionId: z.string().nullable(),
|
|
69
|
+
});
|
|
70
|
+
// ── Attribution — `control` plane (→ agent_capability_roots) ──────────────────
|
|
71
|
+
export const deltaAttributionSchema = z.object({
|
|
72
|
+
/** Legacy single-actor column, derived during the dual-write window. */
|
|
73
|
+
createdBy: z.string().nullable(),
|
|
74
|
+
actorId: z.string().nullable(),
|
|
75
|
+
actorKind: participantKindSchema.nullable(),
|
|
76
|
+
onBehalfOfId: z.string().nullable(),
|
|
77
|
+
onBehalfOfKind: participantKindSchema.nullable(),
|
|
78
|
+
capabilityId: z.string().nullable(),
|
|
79
|
+
confirmationState: confirmationStateSchema.nullable(),
|
|
80
|
+
backfillProvenance: backfillProvenanceSchema.nullable(),
|
|
81
|
+
});
|
|
82
|
+
// ── Provenance — `control` plane (→ tasks) ────────────────────────────────────
|
|
83
|
+
export const deltaProvenanceSchema = z.object({
|
|
84
|
+
/** FK to `Task.id` — the LLM turn that produced this commit. */
|
|
85
|
+
causedByTaskId: z.string().nullable(),
|
|
86
|
+
});
|
|
87
|
+
// ── Full stored row + plane map ───────────────────────────────────────────────
|
|
88
|
+
/** The complete `sync_deltas` row as stored today (core ∪ attribution ∪ provenance). */
|
|
89
|
+
export const syncDeltaRowSchema = syncDeltaCoreSchema
|
|
90
|
+
.extend(deltaAttributionSchema.shape)
|
|
91
|
+
.extend(deltaProvenanceSchema.shape);
|
|
92
|
+
/**
|
|
93
|
+
* Each slice's database plane. The durable answer to "what does a BYO customer DB
|
|
94
|
+
* get?" — only `tenant`-plane slices. Provisioning (P1) reads this instead of
|
|
95
|
+
* hand-coding the boundary; the BYO outbox writes the `tenant` slice and the
|
|
96
|
+
* relay enriches the `control` slices in Ablo's own database.
|
|
97
|
+
*/
|
|
98
|
+
export const DELTA_PLANES = {
|
|
99
|
+
core: 'tenant',
|
|
100
|
+
attribution: 'control',
|
|
101
|
+
provenance: 'control',
|
|
102
|
+
};
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical Zod contract for the WIRE delta — the broadcast object that travels
|
|
3
|
+
* server → client (the `delta` / `sync_response` frame payload). This is the
|
|
4
|
+
* "same contract across both" seam: the SDK client and the sync-server each
|
|
5
|
+
* derive their `SyncDelta` type from THESE schemas via `z.infer`, instead of
|
|
6
|
+
* hand-maintaining two interfaces that drift (they had: the server typed
|
|
7
|
+
* `actionType` as `string` and `createdBy` as a nested ref; the client typed
|
|
8
|
+
* `actionType` as the 8-value union and `createdBy` as a flat string — a silent
|
|
9
|
+
* divergence the client never noticed because it ignores attribution).
|
|
10
|
+
*
|
|
11
|
+
* Distinct from {@link import('./sync-delta-row.js').syncDeltaRowSchema} — that
|
|
12
|
+
* is the STORED ROW (has `organizationId`, flat `actor_id`/`actor_kind`
|
|
13
|
+
* columns, single-char action). The wire delta is a PROJECTION: no
|
|
14
|
+
* `organizationId` (the server-trusted isolation predicate is never broadcast),
|
|
15
|
+
* the full Linear action vocabulary, and attribution hydrated into nested
|
|
16
|
+
* {@link ParticipantRef}s.
|
|
17
|
+
*
|
|
18
|
+
* Shape (per the "shared core + layer extensions" decision):
|
|
19
|
+
* - {@link syncDeltaWireCoreSchema} — the fields BOTH sides agree on.
|
|
20
|
+
* - {@link clientSyncDeltaSchema} — core + the SDK-only extras.
|
|
21
|
+
* - {@link serverSyncDeltaSchema} — core + the audit attribution the server
|
|
22
|
+
* enriches each broadcast with (the client
|
|
23
|
+
* structurally ignores these).
|
|
24
|
+
*
|
|
25
|
+
* Monorepo is on Zod v4.
|
|
26
|
+
*/
|
|
27
|
+
import { z } from 'zod';
|
|
28
|
+
/**
|
|
29
|
+
* `action_type` on the WIRE — the full Linear-compatible vocabulary a broadcast
|
|
30
|
+
* carries (vs the stored row's core CRUD). `I`nsert, `U`pdate, `D`elete,
|
|
31
|
+
* `A`rchive, `V` reVive/unarchive, `C`overing (gained visibility), `G`roupAdded,
|
|
32
|
+
* `S` groupRemoved.
|
|
33
|
+
*/
|
|
34
|
+
export declare const syncDeltaActionSchema: z.ZodEnum<{
|
|
35
|
+
A: "A";
|
|
36
|
+
I: "I";
|
|
37
|
+
U: "U";
|
|
38
|
+
D: "D";
|
|
39
|
+
C: "C";
|
|
40
|
+
G: "G";
|
|
41
|
+
S: "S";
|
|
42
|
+
V: "V";
|
|
43
|
+
}>;
|
|
44
|
+
export type SyncDeltaAction = z.infer<typeof syncDeltaActionSchema>;
|
|
45
|
+
/**
|
|
46
|
+
* A wire delta payload: the post-mutation row object, a control-frame STRING
|
|
47
|
+
* (e.g. a serialized group-change payload on `G`/`S` deltas), or `null` (on
|
|
48
|
+
* deletes). Wider than the stored `data` (row-or-null) precisely because the
|
|
49
|
+
* group/permission frames serialize a string.
|
|
50
|
+
*/
|
|
51
|
+
export declare const wireDeltaDataSchema: z.ZodNullable<z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodString]>>;
|
|
52
|
+
export type WireDeltaData = z.infer<typeof wireDeltaDataSchema>;
|
|
53
|
+
/**
|
|
54
|
+
* A nested participant reference as carried on a BROADCAST delta. The server
|
|
55
|
+
* hydrates the flat `actor_id`/`actor_kind` stored columns into this.
|
|
56
|
+
*/
|
|
57
|
+
export declare const participantRefSchema: z.ZodObject<{
|
|
58
|
+
kind: z.ZodEnum<{
|
|
59
|
+
user: "user";
|
|
60
|
+
agent: "agent";
|
|
61
|
+
system: "system";
|
|
62
|
+
}>;
|
|
63
|
+
id: z.ZodString;
|
|
64
|
+
}, z.core.$strip>;
|
|
65
|
+
export type ParticipantRef = z.infer<typeof participantRefSchema>;
|
|
66
|
+
/**
|
|
67
|
+
* The fields BOTH server and client agree on for a broadcast delta — the shared
|
|
68
|
+
* contract. `transactionId` is modelled as the client sees it (optional string);
|
|
69
|
+
* the server projection widens it to nullable. No `organizationId` (never
|
|
70
|
+
* broadcast). No `createdBy`/attribution here — those types differ per layer and
|
|
71
|
+
* live in the extensions below.
|
|
72
|
+
*/
|
|
73
|
+
export declare const syncDeltaWireCoreSchema: z.ZodObject<{
|
|
74
|
+
id: z.ZodNumber;
|
|
75
|
+
actionType: z.ZodEnum<{
|
|
76
|
+
A: "A";
|
|
77
|
+
I: "I";
|
|
78
|
+
U: "U";
|
|
79
|
+
D: "D";
|
|
80
|
+
C: "C";
|
|
81
|
+
G: "G";
|
|
82
|
+
S: "S";
|
|
83
|
+
V: "V";
|
|
84
|
+
}>;
|
|
85
|
+
modelName: z.ZodString;
|
|
86
|
+
modelId: z.ZodString;
|
|
87
|
+
data: z.ZodNullable<z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodString]>>;
|
|
88
|
+
previousData: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodString]>>>;
|
|
89
|
+
syncGroups: z.ZodArray<z.ZodString>;
|
|
90
|
+
transactionId: z.ZodOptional<z.ZodString>;
|
|
91
|
+
createdAt: z.ZodString;
|
|
92
|
+
}, z.core.$strip>;
|
|
93
|
+
export type SyncDeltaWireCore = z.infer<typeof syncDeltaWireCoreSchema>;
|
|
94
|
+
/**
|
|
95
|
+
* Client projection — core + the SDK-only fields the client reads locally.
|
|
96
|
+
* `z.infer` of this is the SDK's `SyncDelta` (see `sync/SyncWebSocket.ts`).
|
|
97
|
+
*/
|
|
98
|
+
export declare const clientSyncDeltaSchema: z.ZodObject<{
|
|
99
|
+
id: z.ZodNumber;
|
|
100
|
+
actionType: z.ZodEnum<{
|
|
101
|
+
A: "A";
|
|
102
|
+
I: "I";
|
|
103
|
+
U: "U";
|
|
104
|
+
D: "D";
|
|
105
|
+
C: "C";
|
|
106
|
+
G: "G";
|
|
107
|
+
S: "S";
|
|
108
|
+
V: "V";
|
|
109
|
+
}>;
|
|
110
|
+
modelName: z.ZodString;
|
|
111
|
+
modelId: z.ZodString;
|
|
112
|
+
data: z.ZodNullable<z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodString]>>;
|
|
113
|
+
previousData: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodString]>>>;
|
|
114
|
+
syncGroups: z.ZodArray<z.ZodString>;
|
|
115
|
+
transactionId: z.ZodOptional<z.ZodString>;
|
|
116
|
+
createdAt: z.ZodString;
|
|
117
|
+
createdBy: z.ZodOptional<z.ZodString>;
|
|
118
|
+
metadata: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodString]>>>;
|
|
119
|
+
clientMutationId: z.ZodOptional<z.ZodString>;
|
|
120
|
+
}, z.core.$strip>;
|
|
121
|
+
export type ClientSyncDelta = z.infer<typeof clientSyncDeltaSchema>;
|
|
122
|
+
/**
|
|
123
|
+
* Server projection — core + the audit attribution the server enriches each
|
|
124
|
+
* broadcast with (for the audit pane). The client ignores all of it. Overrides
|
|
125
|
+
* `transactionId` to nullable (the server's stored-column reality).
|
|
126
|
+
*/
|
|
127
|
+
export declare const serverSyncDeltaSchema: z.ZodObject<{
|
|
128
|
+
id: z.ZodNumber;
|
|
129
|
+
actionType: z.ZodEnum<{
|
|
130
|
+
A: "A";
|
|
131
|
+
I: "I";
|
|
132
|
+
U: "U";
|
|
133
|
+
D: "D";
|
|
134
|
+
C: "C";
|
|
135
|
+
G: "G";
|
|
136
|
+
S: "S";
|
|
137
|
+
V: "V";
|
|
138
|
+
}>;
|
|
139
|
+
modelName: z.ZodString;
|
|
140
|
+
modelId: z.ZodString;
|
|
141
|
+
data: z.ZodNullable<z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodString]>>;
|
|
142
|
+
previousData: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodString]>>>;
|
|
143
|
+
syncGroups: z.ZodArray<z.ZodString>;
|
|
144
|
+
createdAt: z.ZodString;
|
|
145
|
+
transactionId: z.ZodNullable<z.ZodString>;
|
|
146
|
+
createdBy: z.ZodNullable<z.ZodObject<{
|
|
147
|
+
kind: z.ZodEnum<{
|
|
148
|
+
user: "user";
|
|
149
|
+
agent: "agent";
|
|
150
|
+
system: "system";
|
|
151
|
+
}>;
|
|
152
|
+
id: z.ZodString;
|
|
153
|
+
}, z.core.$strip>>;
|
|
154
|
+
actor: z.ZodNullable<z.ZodObject<{
|
|
155
|
+
kind: z.ZodEnum<{
|
|
156
|
+
user: "user";
|
|
157
|
+
agent: "agent";
|
|
158
|
+
system: "system";
|
|
159
|
+
}>;
|
|
160
|
+
id: z.ZodString;
|
|
161
|
+
}, z.core.$strip>>;
|
|
162
|
+
onBehalfOf: z.ZodNullable<z.ZodObject<{
|
|
163
|
+
kind: z.ZodEnum<{
|
|
164
|
+
user: "user";
|
|
165
|
+
agent: "agent";
|
|
166
|
+
system: "system";
|
|
167
|
+
}>;
|
|
168
|
+
id: z.ZodString;
|
|
169
|
+
}, z.core.$strip>>;
|
|
170
|
+
capabilityId: z.ZodNullable<z.ZodString>;
|
|
171
|
+
confirmationState: z.ZodNullable<z.ZodEnum<{
|
|
172
|
+
auto: "auto";
|
|
173
|
+
previewed: "previewed";
|
|
174
|
+
approved: "approved";
|
|
175
|
+
required_human_approval: "required_human_approval";
|
|
176
|
+
auto_historical: "auto_historical";
|
|
177
|
+
}>>;
|
|
178
|
+
causedByTaskId: z.ZodNullable<z.ZodString>;
|
|
179
|
+
}, z.core.$strip>;
|
|
180
|
+
export type ServerSyncDelta = z.infer<typeof serverSyncDeltaSchema>;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical Zod contract for the WIRE delta — the broadcast object that travels
|
|
3
|
+
* server → client (the `delta` / `sync_response` frame payload). This is the
|
|
4
|
+
* "same contract across both" seam: the SDK client and the sync-server each
|
|
5
|
+
* derive their `SyncDelta` type from THESE schemas via `z.infer`, instead of
|
|
6
|
+
* hand-maintaining two interfaces that drift (they had: the server typed
|
|
7
|
+
* `actionType` as `string` and `createdBy` as a nested ref; the client typed
|
|
8
|
+
* `actionType` as the 8-value union and `createdBy` as a flat string — a silent
|
|
9
|
+
* divergence the client never noticed because it ignores attribution).
|
|
10
|
+
*
|
|
11
|
+
* Distinct from {@link import('./sync-delta-row.js').syncDeltaRowSchema} — that
|
|
12
|
+
* is the STORED ROW (has `organizationId`, flat `actor_id`/`actor_kind`
|
|
13
|
+
* columns, single-char action). The wire delta is a PROJECTION: no
|
|
14
|
+
* `organizationId` (the server-trusted isolation predicate is never broadcast),
|
|
15
|
+
* the full Linear action vocabulary, and attribution hydrated into nested
|
|
16
|
+
* {@link ParticipantRef}s.
|
|
17
|
+
*
|
|
18
|
+
* Shape (per the "shared core + layer extensions" decision):
|
|
19
|
+
* - {@link syncDeltaWireCoreSchema} — the fields BOTH sides agree on.
|
|
20
|
+
* - {@link clientSyncDeltaSchema} — core + the SDK-only extras.
|
|
21
|
+
* - {@link serverSyncDeltaSchema} — core + the audit attribution the server
|
|
22
|
+
* enriches each broadcast with (the client
|
|
23
|
+
* structurally ignores these).
|
|
24
|
+
*
|
|
25
|
+
* Monorepo is on Zod v4.
|
|
26
|
+
*/
|
|
27
|
+
import { z } from 'zod';
|
|
28
|
+
import { participantKindSchema, confirmationStateSchema } from './sync-delta-row.js';
|
|
29
|
+
/**
|
|
30
|
+
* `action_type` on the WIRE — the full Linear-compatible vocabulary a broadcast
|
|
31
|
+
* carries (vs the stored row's core CRUD). `I`nsert, `U`pdate, `D`elete,
|
|
32
|
+
* `A`rchive, `V` reVive/unarchive, `C`overing (gained visibility), `G`roupAdded,
|
|
33
|
+
* `S` groupRemoved.
|
|
34
|
+
*/
|
|
35
|
+
export const syncDeltaActionSchema = z.enum(['I', 'U', 'D', 'A', 'V', 'C', 'G', 'S']);
|
|
36
|
+
/**
|
|
37
|
+
* A wire delta payload: the post-mutation row object, a control-frame STRING
|
|
38
|
+
* (e.g. a serialized group-change payload on `G`/`S` deltas), or `null` (on
|
|
39
|
+
* deletes). Wider than the stored `data` (row-or-null) precisely because the
|
|
40
|
+
* group/permission frames serialize a string.
|
|
41
|
+
*/
|
|
42
|
+
export const wireDeltaDataSchema = z
|
|
43
|
+
.union([z.record(z.string(), z.unknown()), z.string()])
|
|
44
|
+
.nullable();
|
|
45
|
+
/**
|
|
46
|
+
* A nested participant reference as carried on a BROADCAST delta. The server
|
|
47
|
+
* hydrates the flat `actor_id`/`actor_kind` stored columns into this.
|
|
48
|
+
*/
|
|
49
|
+
export const participantRefSchema = z.object({
|
|
50
|
+
kind: participantKindSchema,
|
|
51
|
+
id: z.string(),
|
|
52
|
+
});
|
|
53
|
+
/**
|
|
54
|
+
* The fields BOTH server and client agree on for a broadcast delta — the shared
|
|
55
|
+
* contract. `transactionId` is modelled as the client sees it (optional string);
|
|
56
|
+
* the server projection widens it to nullable. No `organizationId` (never
|
|
57
|
+
* broadcast). No `createdBy`/attribution here — those types differ per layer and
|
|
58
|
+
* live in the extensions below.
|
|
59
|
+
*/
|
|
60
|
+
export const syncDeltaWireCoreSchema = z.object({
|
|
61
|
+
id: z.number(),
|
|
62
|
+
actionType: syncDeltaActionSchema,
|
|
63
|
+
modelName: z.string().min(1),
|
|
64
|
+
modelId: z.string().min(1),
|
|
65
|
+
data: wireDeltaDataSchema,
|
|
66
|
+
previousData: wireDeltaDataSchema.optional(),
|
|
67
|
+
syncGroups: z.array(z.string()),
|
|
68
|
+
transactionId: z.string().optional(),
|
|
69
|
+
createdAt: z.string(),
|
|
70
|
+
});
|
|
71
|
+
/**
|
|
72
|
+
* Client projection — core + the SDK-only fields the client reads locally.
|
|
73
|
+
* `z.infer` of this is the SDK's `SyncDelta` (see `sync/SyncWebSocket.ts`).
|
|
74
|
+
*/
|
|
75
|
+
export const clientSyncDeltaSchema = syncDeltaWireCoreSchema.extend({
|
|
76
|
+
/** @deprecated Flat actor id; superseded by the server's nested `actor`. The
|
|
77
|
+
* client never reads it — kept only so the wire shape round-trips. */
|
|
78
|
+
createdBy: z.string().optional(),
|
|
79
|
+
/** Client-only payload slot (e.g. legacy group-change metadata). */
|
|
80
|
+
metadata: wireDeltaDataSchema.optional(),
|
|
81
|
+
/** Echo-matching id the client correlates against its optimistic mutation. */
|
|
82
|
+
clientMutationId: z.string().optional(),
|
|
83
|
+
});
|
|
84
|
+
/**
|
|
85
|
+
* Server projection — core + the audit attribution the server enriches each
|
|
86
|
+
* broadcast with (for the audit pane). The client ignores all of it. Overrides
|
|
87
|
+
* `transactionId` to nullable (the server's stored-column reality).
|
|
88
|
+
*/
|
|
89
|
+
export const serverSyncDeltaSchema = syncDeltaWireCoreSchema.extend({
|
|
90
|
+
transactionId: z.string().nullable(),
|
|
91
|
+
/** @deprecated Mirrors `actor` 1:1. */
|
|
92
|
+
createdBy: participantRefSchema.nullable(),
|
|
93
|
+
/** Who DID the action. */
|
|
94
|
+
actor: participantRefSchema.nullable(),
|
|
95
|
+
/** On WHOSE AUTHORITY they acted (equals `actor` for human-direct commits). */
|
|
96
|
+
onBehalfOf: participantRefSchema.nullable(),
|
|
97
|
+
/** FK to AgentCapabilityRoot.capabilityId; non-null for agent/system commits. */
|
|
98
|
+
capabilityId: z.string().nullable(),
|
|
99
|
+
confirmationState: confirmationStateSchema.nullable(),
|
|
100
|
+
/** FK to AgentTurn.id — the prompt that caused this delta. */
|
|
101
|
+
causedByTaskId: z.string().nullable(),
|
|
102
|
+
});
|