@abloatai/ablo 0.8.0 → 0.9.1

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 (165) hide show
  1. package/CHANGELOG.md +46 -1
  2. package/README.md +33 -28
  3. package/dist/BaseSyncedStore.d.ts +83 -0
  4. package/dist/BaseSyncedStore.js +194 -2
  5. package/dist/Model.d.ts +42 -0
  6. package/dist/Model.js +103 -44
  7. package/dist/agent/session.js +3 -3
  8. package/dist/ai-sdk/coordination-context.js +4 -0
  9. package/dist/ai-sdk/index.d.ts +56 -47
  10. package/dist/ai-sdk/index.js +56 -47
  11. package/dist/ai-sdk/intent-broadcast.d.ts +5 -0
  12. package/dist/ai-sdk/intent-broadcast.js +11 -4
  13. package/dist/ai-sdk/wrap.d.ts +14 -11
  14. package/dist/ai-sdk/wrap.js +11 -13
  15. package/dist/auth/credentialSource.d.ts +34 -0
  16. package/dist/auth/credentialSource.js +63 -0
  17. package/dist/auth/index.d.ts +2 -22
  18. package/dist/auth/index.js +4 -42
  19. package/dist/auth/schemas.d.ts +35 -0
  20. package/dist/auth/schemas.js +53 -0
  21. package/dist/client/Ablo.d.ts +160 -42
  22. package/dist/client/Ablo.js +145 -75
  23. package/dist/client/ApiClient.d.ts +20 -4
  24. package/dist/client/ApiClient.js +166 -28
  25. package/dist/client/auth.d.ts +14 -5
  26. package/dist/client/auth.js +60 -7
  27. package/dist/client/createInternalComponents.d.ts +2 -0
  28. package/dist/client/createInternalComponents.js +8 -1
  29. package/dist/client/createModelProxy.d.ts +130 -66
  30. package/dist/client/createModelProxy.js +152 -49
  31. package/dist/client/httpClient.d.ts +71 -0
  32. package/dist/client/httpClient.js +69 -0
  33. package/dist/client/identity.d.ts +2 -6
  34. package/dist/client/identity.js +49 -11
  35. package/dist/client/index.d.ts +1 -0
  36. package/dist/client/index.js +1 -0
  37. package/dist/client/registerDataSource.d.ts +3 -3
  38. package/dist/client/registerDataSource.js +11 -9
  39. package/dist/client/validateAbloOptions.js +1 -1
  40. package/dist/core/DatabaseManager.js +30 -2
  41. package/dist/core/openIDBWithTimeout.d.ts +36 -0
  42. package/dist/core/openIDBWithTimeout.js +88 -1
  43. package/dist/errorCodes.d.ts +70 -1
  44. package/dist/errorCodes.js +108 -9
  45. package/dist/errors.d.ts +2 -2
  46. package/dist/errors.js +72 -22
  47. package/dist/index.d.ts +17 -8
  48. package/dist/index.js +15 -6
  49. package/dist/keys/index.d.ts +16 -1
  50. package/dist/keys/index.js +26 -6
  51. package/dist/mutators/UndoManager.d.ts +158 -50
  52. package/dist/mutators/UndoManager.js +345 -22
  53. package/dist/mutators/inverseOp.d.ts +129 -0
  54. package/dist/mutators/inverseOp.js +74 -0
  55. package/dist/mutators/readerActions.d.ts +1 -1
  56. package/dist/mutators/undoApply.d.ts +42 -0
  57. package/dist/mutators/undoApply.js +143 -0
  58. package/dist/query/client.d.ts +10 -9
  59. package/dist/query/client.js +3 -6
  60. package/dist/react/AbloProvider.d.ts +23 -126
  61. package/dist/react/AbloProvider.js +62 -199
  62. package/dist/react/context.d.ts +31 -0
  63. package/dist/react/useAblo.d.ts +2 -2
  64. package/dist/react/useCurrentUserId.d.ts +1 -1
  65. package/dist/react/useCurrentUserId.js +1 -1
  66. package/dist/react/useMutators.js +19 -12
  67. package/dist/schema/ddl.d.ts +34 -3
  68. package/dist/schema/ddl.js +162 -4
  69. package/dist/schema/index.d.ts +5 -1
  70. package/dist/schema/index.js +13 -1
  71. package/dist/schema/model.d.ts +11 -0
  72. package/dist/schema/model.js +2 -0
  73. package/dist/schema/openapi.d.ts +28 -0
  74. package/dist/schema/openapi.js +118 -0
  75. package/dist/schema/plane.d.ts +23 -0
  76. package/dist/schema/plane.js +19 -0
  77. package/dist/schema/relation.d.ts +20 -0
  78. package/dist/schema/serialize.d.ts +4 -0
  79. package/dist/schema/serialize.js +4 -0
  80. package/dist/schema/sync-delta-row.d.ts +157 -0
  81. package/dist/schema/sync-delta-row.js +102 -0
  82. package/dist/schema/sync-delta-wire.d.ts +180 -0
  83. package/dist/schema/sync-delta-wire.js +102 -0
  84. package/dist/server/adapter.d.ts +156 -0
  85. package/dist/server/adapter.js +19 -0
  86. package/dist/server/commit.d.ts +82 -0
  87. package/dist/server/commit.js +1 -0
  88. package/dist/server/index.d.ts +14 -0
  89. package/dist/server/index.js +1 -0
  90. package/dist/server/next.d.ts +51 -0
  91. package/dist/server/next.js +47 -0
  92. package/dist/server/read-config.d.ts +60 -0
  93. package/dist/server/read-config.js +8 -0
  94. package/dist/server/storage-mode.d.ts +17 -0
  95. package/dist/server/storage-mode.js +12 -0
  96. package/dist/source/adapter.d.ts +65 -0
  97. package/dist/source/adapter.js +20 -0
  98. package/dist/source/adapters/drizzle.d.ts +43 -0
  99. package/dist/source/adapters/drizzle.js +185 -0
  100. package/dist/source/adapters/memory.d.ts +12 -0
  101. package/dist/source/adapters/memory.js +114 -0
  102. package/dist/source/adapters/prisma.d.ts +57 -0
  103. package/dist/source/adapters/prisma.js +176 -0
  104. package/dist/source/conformance.d.ts +32 -0
  105. package/dist/source/conformance.js +134 -0
  106. package/dist/source/contract.d.ts +144 -0
  107. package/dist/source/contract.js +99 -0
  108. package/dist/source/index.d.ts +62 -10
  109. package/dist/source/index.js +99 -0
  110. package/dist/source/migrations.d.ts +14 -0
  111. package/dist/source/migrations.js +39 -0
  112. package/dist/source/next.d.ts +33 -0
  113. package/dist/source/next.js +26 -0
  114. package/dist/sync/BootstrapHelper.d.ts +10 -0
  115. package/dist/sync/BootstrapHelper.js +10 -15
  116. package/dist/sync/ConnectionManager.d.ts +55 -1
  117. package/dist/sync/ConnectionManager.js +155 -16
  118. package/dist/sync/HydrationCoordinator.d.ts +93 -17
  119. package/dist/sync/HydrationCoordinator.js +238 -39
  120. package/dist/sync/NetworkProbe.d.ts +58 -24
  121. package/dist/sync/NetworkProbe.js +118 -42
  122. package/dist/sync/SyncWebSocket.d.ts +45 -70
  123. package/dist/sync/SyncWebSocket.js +70 -36
  124. package/dist/sync/createIntentStream.js +10 -1
  125. package/dist/types/streams.d.ts +9 -0
  126. package/dist/utils/mobx-setup.js +1 -0
  127. package/dist/webhooks/events.d.ts +38 -0
  128. package/dist/webhooks/events.js +40 -0
  129. package/dist/webhooks/index.d.ts +10 -0
  130. package/dist/webhooks/index.js +10 -0
  131. package/dist/wire/errorEnvelope.d.ts +34 -0
  132. package/dist/wire/errorEnvelope.js +86 -0
  133. package/dist/wire/frames.d.ts +119 -0
  134. package/dist/wire/frames.js +1 -0
  135. package/dist/wire/index.d.ts +24 -0
  136. package/dist/wire/index.js +21 -0
  137. package/dist/wire/listEnvelope.d.ts +45 -0
  138. package/dist/wire/listEnvelope.js +17 -0
  139. package/docs/api.md +47 -44
  140. package/docs/cli.md +44 -44
  141. package/docs/client-behavior.md +30 -30
  142. package/docs/coordination.md +33 -36
  143. package/docs/data-sources.md +35 -15
  144. package/docs/examples/agent-human.md +45 -43
  145. package/docs/examples/ai-sdk-tool.md +20 -16
  146. package/docs/examples/existing-python-backend.md +16 -12
  147. package/docs/examples/nextjs.md +14 -12
  148. package/docs/examples/scoped-agent.md +1 -1
  149. package/docs/examples/server-agent.md +24 -21
  150. package/docs/guarantees.md +15 -13
  151. package/docs/index.md +2 -2
  152. package/docs/integration-guide.md +30 -30
  153. package/docs/interaction-model.md +19 -23
  154. package/docs/mcp/claude-code.md +3 -3
  155. package/docs/mcp/cursor.md +1 -1
  156. package/docs/mcp/windsurf.md +2 -2
  157. package/docs/mcp.md +6 -6
  158. package/docs/quickstart.md +41 -31
  159. package/docs/react.md +13 -9
  160. package/docs/schema-contract.md +12 -10
  161. package/docs/the-loop.md +21 -0
  162. package/examples/data-source/README.md +4 -5
  163. package/examples/data-source/customer-server.ts +27 -25
  164. package/llms.txt +28 -5
  165. package/package.json +43 -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
+ });