@stndrds/schema 1.0.0-alpha.265 → 1.0.0-alpha.267

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 (47) hide show
  1. package/dist/all--B2_3ksI.d.ts +465 -0
  2. package/dist/all-D5zeUllO.d.mts +465 -0
  3. package/dist/chunk-63WWFZFY.js +1262 -0
  4. package/dist/{chunk-ZBQEMIAV.js → chunk-FDIAOFHS.js} +11 -8
  5. package/dist/chunk-ITGE3PBX.mjs +1215 -0
  6. package/dist/{chunk-UXCJ3NI4.mjs → chunk-KDHDC7E6.mjs} +150 -9
  7. package/dist/{chunk-U36ZIBEM.mjs → chunk-O73ROMWQ.mjs} +15 -6
  8. package/dist/{chunk-QIWADKYA.mjs → chunk-POULKEJM.mjs} +11 -9
  9. package/dist/{chunk-EBGRZUIH.js → chunk-Q4SZAMJT.js} +5 -0
  10. package/dist/{chunk-NGGU6BSN.mjs → chunk-QMLO7V5E.mjs} +6 -6
  11. package/dist/{chunk-L4U5QEQL.js → chunk-QN2N3IJZ.js} +158 -8
  12. package/dist/{chunk-JUKLL5RJ.mjs → chunk-R5LAJCBU.mjs} +5 -2
  13. package/dist/{chunk-NI3HCSYH.js → chunk-V6Q7HCA7.js} +11 -11
  14. package/dist/{chunk-QAF3HNKQ.js → chunk-ZPFOKBIN.js} +16 -5
  15. package/dist/exceptions.d.mts +21 -8
  16. package/dist/exceptions.d.ts +21 -8
  17. package/dist/exceptions.js +42 -38
  18. package/dist/exceptions.mjs +1 -1
  19. package/dist/helpers-C1VVEAOO.d.mts +76 -0
  20. package/dist/helpers-vQ6kp8ET.d.ts +76 -0
  21. package/dist/index-Bq1KrQkR.d.ts +2413 -0
  22. package/dist/index-DtxtOBYT.d.mts +2413 -0
  23. package/dist/index.d.mts +1516 -2212
  24. package/dist/index.d.ts +1516 -2212
  25. package/dist/index.js +1294 -1038
  26. package/dist/index.mjs +911 -905
  27. package/dist/{helpers-eyrnPJEF.d.ts → objects-A1ED9af-.d.ts} +32 -77
  28. package/dist/{helpers-uKLet0kF.d.mts → objects-BCaBw2ef.d.mts} +32 -77
  29. package/dist/validation/all.d.mts +4 -2
  30. package/dist/validation/all.d.ts +4 -2
  31. package/dist/validation/all.js +88 -16
  32. package/dist/validation/all.mjs +9 -9
  33. package/dist/validation/complex/phone.js +2 -2
  34. package/dist/validation/complex/phone.mjs +1 -1
  35. package/dist/validation/config/index.d.mts +5 -18
  36. package/dist/validation/config/index.d.ts +5 -18
  37. package/dist/validation/config/index.js +34 -4
  38. package/dist/validation/config/index.mjs +7 -1
  39. package/dist/validation/object/index.d.mts +2 -2
  40. package/dist/validation/object/index.d.ts +2 -2
  41. package/dist/validation/object/index.js +19 -19
  42. package/dist/validation/object/index.mjs +7 -7
  43. package/dist/validation/primitives/text.js +2 -2
  44. package/dist/validation/primitives/text.mjs +1 -1
  45. package/package.json +2 -2
  46. package/dist/chunk-PGERPYDR.js +0 -2
  47. package/dist/chunk-SP3PNHYF.mjs +0 -1
package/dist/index.mjs CHANGED
@@ -1,28 +1,29 @@
1
1
  import { generateId } from './chunk-QY6QFRRV.mjs';
2
2
  export { asTenantId, asUserId, deepEqual, generateId, indexBy } from './chunk-QY6QFRRV.mjs';
3
- import './chunk-SP3PNHYF.mjs';
4
- import { parseComputedFormula } from './chunk-UXCJ3NI4.mjs';
5
- export { ComputedFormulaParseError, parseAttributeConfig, parseComputedFormula } from './chunk-UXCJ3NI4.mjs';
6
- import { createObjectValidator, createAttributeValidator } from './chunk-NGGU6BSN.mjs';
7
- export { createFormAttributeValidator, rejectUnknownAttributesOrThrow, validateDraft, validateDraftOrThrow, validateObject, validateObjectOrThrow } from './chunk-NGGU6BSN.mjs';
8
- import './chunk-OSSGN43B.mjs';
9
- import './chunk-Q44QKLN4.mjs';
10
- import './chunk-UANQJ2GH.mjs';
11
- import './chunk-U36ZIBEM.mjs';
3
+ import { SYSTEM_FILTER_ATTRIBUTE_TYPES, RESERVED_OBJECT_NAMES, listViewConfigSchema, detailViewConfigSchema, RESERVED_ATTRIBUTE_NAMES, isAttributeSortable, getAttributeCapabilities, resolveIsWithinBounds } from './chunk-ITGE3PBX.mjs';
4
+ export { ATTRIBUTE_FILTER_OPERATORS, LIST_VIEW_TAB_VISIBILITIES, NO_VALUE_OPERATORS, OPERATORS_BY_TYPE, REMOVED_OPERATOR_REPLACEMENTS, RESERVED_ATTRIBUTE_NAMES, RESERVED_OBJECT_NAMES, RESOURCE_VISIBILITIES, SYNONYM_ALIASES, SYSTEM_ATTRIBUTES, SYSTEM_ATTRIBUTE_I18N_KEYS, SYSTEM_FIELD_NAMES, SYSTEM_FILTER_ATTRIBUTE_TYPES, collectQualifiedRuleIssues, currentActor, detailTabSchema, detailViewConfigSchema, getAttributeCapabilities, getAttributeFilterOperators, getRollupFilterOperators, getSystemAttributeI18nKey, getSystemAttributeList, inverseSourceSchema, isAttributeFilterable, isAttributeGroupable, isAttributeKanbanGroupable, isAttributeSearchable, isDynamicValue, isManagedSystemAttribute, isNoValueOperator, isRelativeDateValue, listViewConfigSchema, listViewTabSchema, normalizeFilterRule, normalizeOperator, now, parseViewConfig, relationSourceSchema, resolveIsWithinBounds, tableSourceSchema, toUtcDayString, today, validateQualifiedRule, viewConfigByTypeSchema, viewTypeSchema } from './chunk-ITGE3PBX.mjs';
5
+ import { iconNameSchema, parseAttributeConfigForCreate, parseComputedFormula } from './chunk-KDHDC7E6.mjs';
6
+ export { ComputedFormulaParseError, SCHEMA_LIMITS, colorIdSchema, iconNameSchema, multiselectOptionWriteSchema, parseAttributeConfig, parseAttributeConfigForCreate, parseAttributeConfigForUpdate, parseComputedFormula, selectOptionWriteSchema, statusGroupSchema, statusOptionWriteSchema } from './chunk-KDHDC7E6.mjs';
7
+ import { createObjectValidator, createAttributeValidator } from './chunk-QMLO7V5E.mjs';
8
+ export { createFormAttributeValidator, rejectUnknownAttributesOrThrow, validateDraft, validateDraftOrThrow, validateObject, validateObjectOrThrow } from './chunk-QMLO7V5E.mjs';
12
9
  import './chunk-QVLQPW3O.mjs';
13
10
  import './chunk-ZDQ5AP26.mjs';
14
11
  import './chunk-LV3FEUKU.mjs';
15
12
  import './chunk-UXAHLSWC.mjs';
16
13
  import './chunk-NS63SPNN.mjs';
17
- import { SchemaError, SchemaErrorCode, ValidationError, NotFoundError, DuplicateError } from './chunk-QIWADKYA.mjs';
18
- export { AccessDeniedError, AttributeInUseError, AttributeNotFoundError, ChangeTypeNotSupportedError, ConcurrentModificationError, DestructiveSyncNotAllowedError, DuplicateError, ForbiddenError, MemoryNotFoundError, MigrationTimeoutError, NotFoundError, NotImplementedError, ObjectNotFoundError, ObjectReferencedError, OrphanSystemAttributeError, ProtectedResourceError, ProtectedRoleError, RecordNotFoundError, RecordReferencedError, RepositoryError, RoleNotFoundError, SchemaError, SchemaErrorCode, SearchBackendError, StorageError, SyncCascadeError, SyncConflictError, SyncError, SystemEntityImmutableError, ValidationError, isAttributeInUseError, isNotFoundError, isObjectReferencedError, isProtectedResourceError, isRecordReferencedError, isSchemaError, isValidationError } from './chunk-QIWADKYA.mjs';
14
+ export { createCheckboxValidator } from './chunk-OSSGN43B.mjs';
15
+ export { createDateValidator } from './chunk-Q44QKLN4.mjs';
16
+ export { createNumberValidator } from './chunk-UANQJ2GH.mjs';
17
+ export { TEXT_FORMAT_PATTERNS, createTextValidator, resolveTextPattern } from './chunk-O73ROMWQ.mjs';
18
+ import { SchemaError, SchemaErrorCode, ValidationError, NotFoundError, DuplicateError } from './chunk-POULKEJM.mjs';
19
+ export { AccessDeniedError, AttributeInUseError, AttributeNotFoundError, ChangeTypeNotSupportedError, ConcurrentModificationError, DestructiveSyncNotAllowedError, DuplicateError, ForbiddenError, MemoryNotFoundError, MigrationTimeoutError, NotFoundError, NotImplementedError, ObjectNotFoundError, ObjectReferencedError, OrphanSystemAttributeError, ProtectedResourceError, ProtectedRoleError, RecordNotFoundError, RecordReferencedError, RepositoryError, RoleNotFoundError, SchemaError, SchemaErrorCode, SchemaPlanNotFoundError, SearchBackendError, StorageError, SyncCascadeError, SyncConflictError, SyncError, SystemEntityImmutableError, ValidationError, isAttributeInUseError, isNotFoundError, isObjectReferencedError, isProtectedResourceError, isRecordReferencedError, isSchemaError, isValidationError } from './chunk-POULKEJM.mjs';
19
20
  import './chunk-AYVHMVKQ.mjs';
20
21
  import './chunk-YUFTHPOE.mjs';
21
- import { formatPhoneForDisplay } from './chunk-JUKLL5RJ.mjs';
22
+ import { formatPhoneForDisplay, normalizeCountrylessPhoneNumber, normalizePhoneNumber } from './chunk-R5LAJCBU.mjs';
22
23
  import './chunk-GO6LQADH.mjs';
23
24
  export { DEFAULT_VALIDATION_MESSAGES, formatZodErrors } from './chunk-HRQEZUAA.mjs';
24
25
  import { ICONS, SKILL_NAME_MAX_LENGTH, SKILL_DESCRIPTION_MAX_LENGTH, MEMORY_NAME_MAX_LENGTH, MEMORY_DESCRIPTION_MAX_LENGTH, getCountryDisplayNameByIso3 } from '@stndrds/constants';
25
- import z3, { z } from 'zod';
26
+ import z2, { z } from 'zod';
26
27
 
27
28
  // src/types/notifications.ts
28
29
  var NOTIFICATION_KINDS = ["fyi", "task", "question", "handoff", "system"];
@@ -67,408 +68,6 @@ var BEHAVIOR_PROPERTIES = [
67
68
  ];
68
69
  var PRESENTATION_PROPERTIES = ["label", "description", "placeholder", "icon"];
69
70
 
70
- // src/types/system-attributes.ts
71
- var SYSTEM_ATTRIBUTE_I18N_KEYS = {
72
- createdAt: "createdAt",
73
- updatedAt: "updatedAt",
74
- createdBy: "createdBy",
75
- lastUpdatedBy: "lastUpdatedBy",
76
- attachments: "attachments"
77
- };
78
- function getSystemAttributeI18nKey(name) {
79
- return SYSTEM_ATTRIBUTE_I18N_KEYS[name];
80
- }
81
- var SYSTEM_ATTRIBUTES = {
82
- createdAt: {
83
- id: "system:createdAt",
84
- name: "createdAt",
85
- label: "Created time",
86
- type: "date",
87
- required: false,
88
- system: true,
89
- icon: "clock-circle",
90
- description: "When this record was created"
91
- },
92
- updatedAt: {
93
- id: "system:updatedAt",
94
- name: "updatedAt",
95
- label: "Last edited time",
96
- type: "date",
97
- required: false,
98
- system: true,
99
- icon: "clock-circle",
100
- description: "When this record was last modified"
101
- },
102
- createdBy: {
103
- id: "system:createdBy",
104
- name: "createdBy",
105
- label: "Created by",
106
- type: "user",
107
- required: false,
108
- system: true,
109
- multiple: false,
110
- icon: "user",
111
- description: "Actor who created this record"
112
- },
113
- lastUpdatedBy: {
114
- id: "system:lastUpdatedBy",
115
- name: "lastUpdatedBy",
116
- label: "Last edited by",
117
- type: "user",
118
- required: false,
119
- system: true,
120
- multiple: false,
121
- icon: "user",
122
- description: "Actor who last modified this record"
123
- },
124
- /**
125
- * System attribute for free-form document attachments.
126
- * Hidden from forms, visible in Documents tab.
127
- * Users can attach any document without template constraints.
128
- */
129
- attachments: {
130
- id: "system:attachments",
131
- name: "attachments",
132
- label: "Attachments",
133
- type: "document",
134
- required: false,
135
- system: true,
136
- hidden: true,
137
- // Hidden from regular form views
138
- icon: "paperclip",
139
- description: "Free-form document attachments"
140
- }
141
- };
142
- function getSystemAttributeList() {
143
- return Object.values(SYSTEM_ATTRIBUTES);
144
- }
145
- function isManagedSystemAttribute(attribute) {
146
- return attribute.id?.startsWith("system:") ?? false;
147
- }
148
-
149
- // src/types/attribute-capabilities.ts
150
- var TEXT_OPERATORS = [
151
- "is",
152
- "is_not",
153
- "contains",
154
- "not_contains",
155
- "starts_with",
156
- "ends_with",
157
- "is_empty",
158
- "is_not_empty"
159
- ];
160
- var NUMBER_OPERATORS = [
161
- "eq",
162
- "neq",
163
- "lt",
164
- "gt",
165
- "lte",
166
- "gte",
167
- "is_empty",
168
- "is_not_empty"
169
- ];
170
- var CHECKBOX_OPERATORS = [
171
- "is_checked",
172
- "is_not_checked"
173
- ];
174
- var DATE_OPERATORS = [
175
- "is",
176
- "is_not",
177
- "before",
178
- "after",
179
- "on_or_before",
180
- "on_or_after",
181
- "is_within",
182
- "day_month_eq",
183
- "is_empty",
184
- "is_not_empty"
185
- ];
186
- var SELECT_OPERATORS = [
187
- "is",
188
- "is_not",
189
- "any_of",
190
- "none_of",
191
- "is_empty",
192
- "is_not_empty"
193
- ];
194
- var MULTISELECT_OPERATORS = [
195
- "contains",
196
- "not_contains",
197
- "is_empty",
198
- "is_not_empty"
199
- ];
200
- var REFERENCE_OPERATORS = [
201
- "is",
202
- "is_not",
203
- "any_of",
204
- "none_of",
205
- "contains",
206
- "not_contains",
207
- "is_empty",
208
- "is_not_empty"
209
- ];
210
- var PRESENCE_OPERATORS = [
211
- "is_empty",
212
- "is_not_empty"
213
- ];
214
- var FORMULA_OPERATORS = [
215
- "is",
216
- "is_not",
217
- "eq",
218
- "neq",
219
- "lt",
220
- "gt",
221
- "lte",
222
- "gte",
223
- "contains",
224
- "not_contains",
225
- "is_empty",
226
- "is_not_empty"
227
- ];
228
- var ATTRIBUTE_FILTER_OPERATORS = {
229
- text: TEXT_OPERATORS,
230
- richtext: [],
231
- number: NUMBER_OPERATORS,
232
- checkbox: CHECKBOX_OPERATORS,
233
- date: DATE_OPERATORS,
234
- phone: ["is", "is_not", "contains", "not_contains", "is_empty", "is_not_empty"],
235
- currency: NUMBER_OPERATORS,
236
- status: SELECT_OPERATORS,
237
- select: SELECT_OPERATORS,
238
- multiselect: MULTISELECT_OPERATORS,
239
- location: [],
240
- user: REFERENCE_OPERATORS,
241
- relation: REFERENCE_OPERATORS,
242
- formula: FORMULA_OPERATORS,
243
- document: PRESENCE_OPERATORS
244
- };
245
- var COMPUTED_TYPES = /* @__PURE__ */ new Set(["formula", "rollup"]);
246
- var EDGE_BACKED_TYPES = /* @__PURE__ */ new Set(["user", "relation", "document"]);
247
- var STATIC_DEFAULT_TYPES = /* @__PURE__ */ new Set([
248
- "text",
249
- "richtext",
250
- "number",
251
- "select",
252
- "multiselect",
253
- "status",
254
- "date",
255
- "phone",
256
- "currency",
257
- "location",
258
- "user",
259
- "relation",
260
- "document"
261
- ]);
262
- var PLACEHOLDER_TYPES = /* @__PURE__ */ new Set([
263
- "text",
264
- "number",
265
- "date",
266
- "phone",
267
- "currency",
268
- "select",
269
- "multiselect"
270
- ]);
271
- var SEARCHABLE_TYPES = /* @__PURE__ */ new Set([
272
- "text",
273
- "phone",
274
- "status",
275
- "select",
276
- "multiselect"
277
- ]);
278
- var SORTABLE_TYPES = /* @__PURE__ */ new Set([
279
- "text",
280
- "number",
281
- "checkbox",
282
- "date",
283
- "phone",
284
- "currency",
285
- "status",
286
- "select"
287
- ]);
288
- function getAttributeCapabilities(attribute) {
289
- const suppressed = Boolean(attribute.hidden || attribute.archived);
290
- const active = !attribute.archived;
291
- const computed = COMPUTED_TYPES.has(attribute.type);
292
- const document2 = attribute.type === "document";
293
- const edgeBacked = EDGE_BACKED_TYPES.has(attribute.type);
294
- const cardinality = getAttributeCardinality(attribute);
295
- const operators = suppressed ? [] : getRawFilterOperators(attribute);
296
- const filterable = operators.length > 0 && !suppressed;
297
- const searchable = !suppressed && SEARCHABLE_TYPES.has(attribute.type);
298
- const sortable = !suppressed && SORTABLE_TYPES.has(attribute.type);
299
- const groupable = !suppressed && isGroupableType(attribute.type);
300
- const kanbanGroupable = !suppressed && attribute.type === "status";
301
- const managed = isManagedSystemAttribute(attribute);
302
- const readOnly = computed || document2 || managed;
303
- const editable = !(suppressed || readOnly);
304
- const required = isRequiredForbidden(attribute.type) ? "forbidden" : "allowed";
305
- const defaultValue = getDefaultValueCapability(attribute.type);
306
- const maxItems = supportsMaxItems(attribute);
307
- const placeholder = PLACEHOLDER_TYPES.has(attribute.type);
308
- const warningWhenDeprecated = Boolean(attribute.deprecated && !suppressed);
309
- const editMode = resolveEditMode(attribute);
310
- return {
311
- lifecycle: {
312
- active,
313
- deprecated: Boolean(attribute.deprecated),
314
- visibleInArchitect: true,
315
- visibleInRuntime: !suppressed,
316
- warningWhenDeprecated
317
- },
318
- storage: {
319
- mode: computed ? "computed" : edgeBacked ? "edge" : "value",
320
- cardinality,
321
- edgeBacked,
322
- preservesExistingValues: Boolean(attribute.archived),
323
- qualifiedProperties: supportsQualifiedProperties(attribute.type),
324
- polymorphic: getPolymorphicCapability(attribute),
325
- maxItems
326
- },
327
- authoring: {
328
- editable,
329
- readOnly,
330
- directEdit: editable && editMode === "inline",
331
- required,
332
- defaultValue,
333
- placeholder,
334
- maxItems
335
- },
336
- presentation: {
337
- formField: !suppressed && isFormFieldType(attribute.type),
338
- tableCell: !suppressed && isTableCellType(attribute.type),
339
- defaultColumn: !suppressed && isDefaultColumnType(attribute.type),
340
- compactDisplay: !suppressed,
341
- popoverEditor: !suppressed && editMode === "popover",
342
- placeholder,
343
- warningWhenDeprecated
344
- },
345
- query: {
346
- filterable,
347
- searchable,
348
- sortable,
349
- groupable,
350
- kanbanGroupable,
351
- operators
352
- },
353
- agent: {
354
- readable: !suppressed,
355
- writable: editable && !document2,
356
- compactReadable: !suppressed,
357
- contentReadable: !suppressed && isContentReadableType(attribute.type),
358
- requiresDedicatedTool: document2
359
- },
360
- exchange: {
361
- importable: !suppressed,
362
- exportable: !suppressed,
363
- schemaExportable: true,
364
- metadataExportable: false
365
- }
366
- };
367
- }
368
- function getAttributeFilterOperators(attribute) {
369
- return getAttributeCapabilities(attribute).query.operators;
370
- }
371
- function isAttributeFilterable(attribute) {
372
- return getAttributeCapabilities(attribute).query.filterable;
373
- }
374
- function isAttributeSearchable(attribute) {
375
- return getAttributeCapabilities(attribute).query.searchable;
376
- }
377
- function isAttributeSortable(attribute) {
378
- return getAttributeCapabilities(attribute).query.sortable;
379
- }
380
- function isAttributeGroupable(attribute) {
381
- return getAttributeCapabilities(attribute).query.groupable;
382
- }
383
- function isAttributeKanbanGroupable(attribute) {
384
- return getAttributeCapabilities(attribute).query.kanbanGroupable;
385
- }
386
- function getRollupFilterOperators(attr) {
387
- const fn = attr.function;
388
- if (fn === "earliest" || fn === "latest") {
389
- return ATTRIBUTE_FILTER_OPERATORS.date;
390
- }
391
- if (fn === "original") {
392
- const targetType = attr.targetAttributeType;
393
- if (targetType && hasFilterOperatorEntry(targetType)) {
394
- return ATTRIBUTE_FILTER_OPERATORS[targetType];
395
- }
396
- return ATTRIBUTE_FILTER_OPERATORS.number;
397
- }
398
- return ATTRIBUTE_FILTER_OPERATORS.number;
399
- }
400
- function getRawFilterOperators(attribute) {
401
- if (attribute.type === "rollup") {
402
- return getRollupFilterOperators(attribute);
403
- }
404
- return ATTRIBUTE_FILTER_OPERATORS[attribute.type] ?? [];
405
- }
406
- function getAttributeCardinality(attribute) {
407
- if (attribute.type === "multiselect" || attribute.type === "document") return "many";
408
- if (attribute.type === "user" && attribute.multiple === true) return "many";
409
- if (attribute.type === "relation") return attribute.cardinality === "many" ? "many" : "one";
410
- return "one";
411
- }
412
- function getPolymorphicCapability(attribute) {
413
- if (attribute.type !== "relation") return "none";
414
- const relation2 = attribute;
415
- const targets = relation2.targets ?? [];
416
- if (targets.length === 1 && targets[0]?.object === "*") return "internal";
417
- return targets.length > 1 ? "code-only" : "none";
418
- }
419
- function supportsMaxItems(attribute) {
420
- if (attribute.type === "multiselect") return true;
421
- if (attribute.type === "relation") return attribute.cardinality === "many";
422
- return false;
423
- }
424
- function supportsQualifiedProperties(type) {
425
- return type === "relation" || type === "document";
426
- }
427
- function isRequiredForbidden(type) {
428
- return type === "checkbox" || type === "formula" || type === "rollup";
429
- }
430
- function getDefaultValueCapability(type) {
431
- if (type === "checkbox") return "automatic";
432
- if (type === "formula" || type === "rollup") return "forbidden";
433
- if (STATIC_DEFAULT_TYPES.has(type)) return "static";
434
- return "forbidden";
435
- }
436
- function isDefaultColumnType(type) {
437
- return isTableCellType(type);
438
- }
439
- function isTableCellType(type) {
440
- return type !== "richtext" && type !== "document";
441
- }
442
- function isFormFieldType(type) {
443
- return type !== "richtext";
444
- }
445
- function resolveEditMode(attribute) {
446
- switch (attribute.type) {
447
- case "checkbox":
448
- return "inline";
449
- case "number":
450
- return attribute.renderAs === "rating" ? "inline" : "default";
451
- case "select":
452
- case "multiselect":
453
- return attribute.renderAs === "badges" ? "inline" : "popover";
454
- case "status":
455
- case "relation":
456
- case "user":
457
- return "popover";
458
- default:
459
- return "default";
460
- }
461
- }
462
- function isGroupableType(type) {
463
- return type === "status" || type === "currency";
464
- }
465
- function isContentReadableType(type) {
466
- return type === "richtext" || type === "document";
467
- }
468
- function hasFilterOperatorEntry(type) {
469
- return Object.prototype.hasOwnProperty.call(ATTRIBUTE_FILTER_OPERATORS, type);
470
- }
471
-
472
71
  // src/types/attributes.ts
473
72
  var RELATION_TARGET_ANY = "*";
474
73
  function isUniversalRelation(attr) {
@@ -489,10 +88,12 @@ var AUDIT_RESOURCE_TYPES = [
489
88
  "record",
490
89
  "object",
491
90
  "attribute",
91
+ "view",
492
92
  "user",
493
93
  "role",
494
94
  "settings",
495
- "file"
95
+ "file",
96
+ "agent"
496
97
  ];
497
98
  var AUDIT_ACTIONS = [
498
99
  // Records
@@ -509,6 +110,10 @@ var AUDIT_ACTIONS = [
509
110
  "attribute.created",
510
111
  "attribute.updated",
511
112
  "attribute.deleted",
113
+ // Schema - Views
114
+ "view.created",
115
+ "view.updated",
116
+ "view.deleted",
512
117
  // Users
513
118
  "user.created",
514
119
  "user.invited",
@@ -530,6 +135,32 @@ var AUDIT_ACTIONS = [
530
135
  "file.deleted"
531
136
  ];
532
137
 
138
+ // src/types/agent.ts
139
+ var SESSION_TERMINAL_STATUSES = [
140
+ "completed",
141
+ "failed",
142
+ "cancelled",
143
+ "timeout",
144
+ "expired"
145
+ ];
146
+ function isTerminalSessionStatus(status2) {
147
+ return SESSION_TERMINAL_STATUSES.includes(status2);
148
+ }
149
+ var DEFAULT_APPROVAL_POLICY = Object.freeze({
150
+ mutation: "ask",
151
+ destructive: "ask",
152
+ outward: "ask"
153
+ });
154
+ var TODO_PLAN_STATUSES = ["active", "completed", "promoted", "abandoned"];
155
+ function agentDisplayName(agent2) {
156
+ return agent2.label?.trim() || agent2.name;
157
+ }
158
+ var TODO_STATUSES = ["pending", "in_progress", "completed", "blocked"];
159
+ var MAX_TODOS = 50;
160
+ var MAX_TODO_ID_CHARS = 80;
161
+ var MAX_TODO_DESCRIPTION_CHARS = 500;
162
+ var MAX_TODO_RESULT_CHARS = 2e3;
163
+
533
164
  // src/types/document-layout.ts
534
165
  var MAX_PRESET_DEPTH = 5;
535
166
 
@@ -545,21 +176,6 @@ function getErrorMessage(error) {
545
176
  return String(error);
546
177
  }
547
178
 
548
- // src/types/filters.ts
549
- var OPERATORS_BY_TYPE = ATTRIBUTE_FILTER_OPERATORS;
550
- var NO_VALUE_OPERATORS = [
551
- "is_empty",
552
- "is_not_empty",
553
- "is_checked",
554
- "is_not_checked"
555
- ];
556
- function isNoValueOperator(operator) {
557
- return NO_VALUE_OPERATORS.includes(operator);
558
- }
559
- function getRollupFilterOperators2(attr) {
560
- return getRollupFilterOperators(attr);
561
- }
562
-
563
179
  // src/types/forms/definition.ts
564
180
  function isFormDefinition(obj) {
565
181
  return typeof obj === "object" && obj !== null && "slots" in obj && "steps" in obj && "name" in obj && typeof obj.name === "string" && Array.isArray(obj.slots) && Array.isArray(obj.steps);
@@ -612,29 +228,6 @@ var NoopGeocodingAdapter = class {
612
228
  }
613
229
  };
614
230
 
615
- // src/types/objects.ts
616
- var SYSTEM_FIELD_NAMES = [
617
- "id",
618
- "createdAt",
619
- "updatedAt",
620
- "createdBy",
621
- "lastUpdatedBy"
622
- ];
623
- var RESERVED_ATTRIBUTE_NAMES = [
624
- // System fields (auto-managed)
625
- ...SYSTEM_FIELD_NAMES,
626
- // Other ObjectRecord properties
627
- "objectId",
628
- "label",
629
- "embeddingText",
630
- "values",
631
- "metadata",
632
- "deletedAt",
633
- "deletedBy",
634
- "schemaVersion"
635
- ];
636
- var RESERVED_OBJECT_NAMES = ["skill"];
637
-
638
231
  // src/types/permissions.ts
639
232
  var ALL_ACTIONS = ["read", "create", "update", "delete", "manage"];
640
233
  function actionsToAccessLevel(actions) {
@@ -670,6 +263,11 @@ function hasOptions(attr) {
670
263
  // src/types/user-profiles.ts
671
264
  var USER_STATUSES = ["active", "suspended"];
672
265
 
266
+ // src/types/schema-state.ts
267
+ function viewStateKey(view) {
268
+ return `${view.object}:${view.name}:${view.type}`;
269
+ }
270
+
673
271
  // src/types/views.ts
674
272
  function isDetailView(view) {
675
273
  return view.type === "detail";
@@ -678,12 +276,15 @@ function isListView(view) {
678
276
  return view.type === "list";
679
277
  }
680
278
  function isFieldGroup(group2) {
681
- return !group2.type || group2.type === "fields";
279
+ return group2.type === "fields";
682
280
  }
683
281
  function isRelationGroup(group2) {
684
282
  return group2.type === "relation";
685
283
  }
686
284
 
285
+ // src/types/pagination.ts
286
+ var ESTIMATED_COUNT_CAP = 1e4;
287
+
687
288
  // src/lib/object-helpers.ts
688
289
  function isEmptyObject(obj) {
689
290
  if (obj === null || obj === void 0) {
@@ -701,6 +302,21 @@ function toUndefinedIfEmpty(obj) {
701
302
  return isNotEmpty(obj) ? obj : void 0;
702
303
  }
703
304
 
305
+ // src/lib/byte-size.ts
306
+ var MAX_UNIT_INDEX = 4;
307
+ function computeByteMagnitude(bytes) {
308
+ if (bytes <= 0) return { value: 0, unitIndex: 0 };
309
+ const k = 1e3;
310
+ const unitIndex = Math.min(MAX_UNIT_INDEX, Math.floor(Math.log(bytes) / Math.log(k)));
311
+ const value = Number.parseFloat((bytes / k ** unitIndex).toFixed(1));
312
+ return { value, unitIndex };
313
+ }
314
+ var BYTE_UNIT_LABELS = ["B", "KB", "MB", "GB", "TB"];
315
+ function formatByteSize(bytes) {
316
+ const { value, unitIndex } = computeByteMagnitude(bytes);
317
+ return `${value} ${BYTE_UNIT_LABELS[unitIndex]}`;
318
+ }
319
+
704
320
  // src/lib/document-attribute.ts
705
321
  var DOCUMENT_SYSTEM_ATTRIBUTES = {
706
322
  ATTACHMENTS: "attachments"
@@ -708,13 +324,13 @@ var DOCUMENT_SYSTEM_ATTRIBUTES = {
708
324
  function isDocumentAttribute(attr) {
709
325
  return attr.type === "document";
710
326
  }
711
- function matchesMime(mime, accepted) {
712
- if (!accepted || accepted.length === 0) return true;
713
- return accepted.some((pattern) => {
714
- if (pattern.endsWith("/*")) {
715
- return mime.startsWith(pattern.slice(0, -1));
716
- }
717
- return mime === pattern;
327
+ function matchesAccepts(file, accepts) {
328
+ if (!accepts || accepts.length === 0) return true;
329
+ const name = file.name.toLowerCase();
330
+ return accepts.some((pattern) => {
331
+ if (pattern.endsWith("/*")) return file.mimeType.startsWith(pattern.slice(0, -1));
332
+ if (pattern.startsWith(".")) return name.endsWith(pattern.toLowerCase());
333
+ return file.mimeType === pattern;
718
334
  });
719
335
  }
720
336
 
@@ -968,6 +584,19 @@ var labelExpressionSchema = z.string().min(1, "labelExpression cannot be empty")
968
584
  message: `Invalid pipe name. Valid pipes: ${ALL_PIPES.join(", ")}`
969
585
  }
970
586
  );
587
+ function validateLabelExpression(expression) {
588
+ const result = labelExpressionSchema.safeParse(expression);
589
+ if (!result.success) {
590
+ return {
591
+ success: false,
592
+ error: result.error.issues[0]?.message ?? "Invalid labelExpression"
593
+ };
594
+ }
595
+ return {
596
+ success: true,
597
+ attributes: extractAttributeNames(expression)
598
+ };
599
+ }
971
600
  var simplePipes = {
972
601
  /** Convert to uppercase */
973
602
  UPPER: (v) => String(v).toUpperCase(),
@@ -1126,6 +755,13 @@ function getUserDisplayName(user2) {
1126
755
  return user2.email?.split("@")[0] ?? "";
1127
756
  }
1128
757
 
758
+ // src/lib/record-creator.ts
759
+ var RECORD_CREATOR_ROOT_ACTOR_METADATA_KEY = "__creatorRootActorId";
760
+ function getRecordCreatorPrincipalId(record) {
761
+ const creatorRootActorId = record.metadata?.[RECORD_CREATOR_ROOT_ACTOR_METADATA_KEY];
762
+ return typeof creatorRootActorId === "string" && creatorRootActorId.length > 0 ? creatorRootActorId : record.createdBy;
763
+ }
764
+
1129
765
  // src/constants/attribute-columns.ts
1130
766
  var DB_COLUMN_FIELDS = /* @__PURE__ */ new Set([
1131
767
  "id",
@@ -1267,6 +903,19 @@ var VALID_ICONS = new Set(ICONS);
1267
903
  var ATTRIBUTE_NAME_REGEX = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
1268
904
  var MAX_NAME_LENGTH = 63;
1269
905
  var MAX_LABEL_LENGTH = 128;
906
+ var OBJECT_NAME_SCHEMA = z2.string().min(1, "Object name cannot be empty").max(63, "Object name is too long (max 63 characters)").regex(/^[a-z][a-z0-9-]*$/, {
907
+ message: "Invalid object name format.\nName must be in kebab-case (slug format):\n \u2705 Valid: 'products', 'user-profiles', 'order-items'\n \u274C Invalid: 'Products', 'userProfiles', 'user_profiles'"
908
+ });
909
+ function validateObjectName(name) {
910
+ try {
911
+ OBJECT_NAME_SCHEMA.parse(name);
912
+ } catch (error) {
913
+ if (error instanceof z2.ZodError) {
914
+ throw new SchemaError(error.issues[0].message, SchemaErrorCode.INVALID_OBJECT_NAME);
915
+ }
916
+ throw error;
917
+ }
918
+ }
1270
919
  function assertUniqueBy(items, getKey, buildError) {
1271
920
  const seen = /* @__PURE__ */ new Set();
1272
921
  for (const item of items) {
@@ -1363,12 +1012,28 @@ var AgentBuilder = class {
1363
1012
  if (!config.name || config.name.trim().length === 0) {
1364
1013
  throw new ValidationError("Agent name is required", []);
1365
1014
  }
1366
- this.bp = { name: config.name, system: true, triggers: [] };
1015
+ this.bp = { name: config.name, system: true, visibility: "workspace", triggers: [] };
1367
1016
  }
1368
1017
  description(value) {
1369
1018
  this.bp.description = value;
1370
1019
  return this;
1371
1020
  }
1021
+ /**
1022
+ * Display text shown wherever this agent's identity is rendered in the
1023
+ * UI — a separate concern from `name` (the stable identity the boot sync
1024
+ * matches rows on). Falls back to `name` when never called.
1025
+ *
1026
+ * @example
1027
+ * ```typescript
1028
+ * agent({ name: "architecte" })
1029
+ * .label("Architecte")
1030
+ * // ...
1031
+ * ```
1032
+ */
1033
+ label(value) {
1034
+ this.bp.label = value;
1035
+ return this;
1036
+ }
1372
1037
  icon(value) {
1373
1038
  this.bp.icon = value;
1374
1039
  return this;
@@ -1407,6 +1072,32 @@ var AgentBuilder = class {
1407
1072
  Object.assign(this.bp, value);
1408
1073
  return this;
1409
1074
  }
1075
+ approval(value) {
1076
+ this.bp.approval = { ...DEFAULT_APPROVAL_POLICY, ...this.bp.approval, ...value };
1077
+ return this;
1078
+ }
1079
+ /** Runtime-agent visibility. Code-declared system agents must stay workspace-visible. */
1080
+ visibility(value) {
1081
+ this.bp.visibility = value;
1082
+ return this;
1083
+ }
1084
+ /**
1085
+ * Gate this agent behind a system permission: an actor lacking `action` on
1086
+ * `resource` never sees it in the agent list and cannot open a session
1087
+ * against it. Reuses the same permission vocabulary that guards the
1088
+ * matching HTTP surface — do not invent a new resource/action pair.
1089
+ *
1090
+ * @example
1091
+ * ```typescript
1092
+ * agent({ name: "architecte" })
1093
+ * .requiresPermission("architect", "update")
1094
+ * // ...
1095
+ * ```
1096
+ */
1097
+ requiresPermission(resource, action) {
1098
+ this.bp.requiredPermission = { resource, action };
1099
+ return this;
1100
+ }
1410
1101
  /**
1411
1102
  * Declare a trigger. `name` is the stable identity the boot sync uses to
1412
1103
  * reconcile trigger rows; `enabled` defaults to true.
@@ -1439,6 +1130,12 @@ var AgentBuilder = class {
1439
1130
  if (!this.bp.model) {
1440
1131
  throw new ValidationError(`Agent "${this.bp.name}": model is required`, []);
1441
1132
  }
1133
+ if (this.bp.system && this.bp.visibility === "private") {
1134
+ throw new ValidationError(
1135
+ `Agent "${this.bp.name}": system agents must use workspace visibility`,
1136
+ []
1137
+ );
1138
+ }
1442
1139
  assertUniqueBy(
1443
1140
  this.bp.triggers,
1444
1141
  (t) => t.name,
@@ -1446,6 +1143,7 @@ var AgentBuilder = class {
1446
1143
  );
1447
1144
  return {
1448
1145
  ...this.bp,
1146
+ visibility: this.bp.visibility ?? "workspace",
1449
1147
  config: this.bp.config ?? DEFAULT_AGENT_EXECUTION_CONFIG,
1450
1148
  systemPrompt: this.bp.systemPrompt,
1451
1149
  model: this.bp.model
@@ -1617,6 +1315,7 @@ var TextAttributeBuilder = class extends BaseAttributeBuilder {
1617
1315
  }
1618
1316
  pattern(value) {
1619
1317
  this.attr.pattern = value;
1318
+ this.attr.format = void 0;
1620
1319
  return this;
1621
1320
  }
1622
1321
  multiline(value = true) {
@@ -1635,21 +1334,24 @@ var TextAttributeBuilder = class extends BaseAttributeBuilder {
1635
1334
  * Set email validation pattern
1636
1335
  */
1637
1336
  email() {
1638
- this.attr.pattern = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
1337
+ this.attr.format = "email";
1338
+ this.attr.pattern = void 0;
1639
1339
  return this;
1640
1340
  }
1641
1341
  /**
1642
1342
  * Set URL validation pattern
1643
1343
  */
1644
1344
  url() {
1645
- this.attr.pattern = "^https?:\\/\\/[\\w\\-]+(\\.[\\w\\-]+)+[/#?]?.*$";
1345
+ this.attr.format = "url";
1346
+ this.attr.pattern = void 0;
1646
1347
  return this;
1647
1348
  }
1648
1349
  /**
1649
1350
  * Set slug validation pattern
1650
1351
  */
1651
1352
  slug() {
1652
- this.attr.pattern = "^[a-z0-9]+(?:-[a-z0-9]+)*$";
1353
+ this.attr.format = "slug";
1354
+ this.attr.pattern = void 0;
1653
1355
  return this;
1654
1356
  }
1655
1357
  };
@@ -3018,17 +2720,7 @@ var ObjectBuilder = class {
3018
2720
  if (name === void 0) {
3019
2721
  return;
3020
2722
  }
3021
- const objectNameSchema = z3.string().min(1, "Object name cannot be empty").max(63, "Object name is too long (max 63 characters)").regex(/^[a-z][a-z0-9-]*$/, {
3022
- message: "Invalid object name format.\nName must be in kebab-case (slug format):\n \u2705 Valid: 'products', 'user-profiles', 'order-items'\n \u274C Invalid: 'Products', 'userProfiles', 'user_profiles'"
3023
- });
3024
- try {
3025
- objectNameSchema.parse(name);
3026
- } catch (error) {
3027
- if (error instanceof z3.ZodError) {
3028
- throw new SchemaError(error.issues[0].message, SchemaErrorCode.INVALID_OBJECT_NAME);
3029
- }
3030
- throw error;
3031
- }
2723
+ validateObjectName(name);
3032
2724
  }
3033
2725
  };
3034
2726
  function object(config) {
@@ -3063,7 +2755,7 @@ function validatePresetStructure(presetId, nodes, depth) {
3063
2755
  }
3064
2756
  var GroupBuilder = class {
3065
2757
  constructor(id, label) {
3066
- this.data = { fields: [] };
2758
+ this.data = { type: "fields", fields: [] };
3067
2759
  this.data.id = id;
3068
2760
  this.data.label = label;
3069
2761
  }
@@ -3185,17 +2877,6 @@ var RelationGroupBuilder = class {
3185
2877
  this.data.allowCreate = value;
3186
2878
  return this;
3187
2879
  }
3188
- /**
3189
- * Enable two-level traversal (through mode).
3190
- * Parent rows become grouping headers; sub-rows from `attribute` are the primary display.
3191
- *
3192
- * @param attribute - Relation attribute on the first-level target object
3193
- * @example .through("companies") — display companies linked via each member
3194
- */
3195
- through(attribute) {
3196
- this.data.through = { attribute };
3197
- return this;
3198
- }
3199
2880
  /**
3200
2881
  * Build the relation group definition
3201
2882
  */
@@ -3316,29 +2997,6 @@ var TableTabConfig = class {
3316
2997
  this.tabData.sorts.push({ attribute, direction });
3317
2998
  return this;
3318
2999
  }
3319
- /**
3320
- * Traverse a 2nd-level relation to display nested data.
3321
- * When active, `tab.columns` stores the 2nd-level object's attribute names.
3322
- *
3323
- * @param attribute - Relation attribute on the first-level target object
3324
- * @example .table("members").through("companies").columns(["name", "sector"])
3325
- */
3326
- through(attribute) {
3327
- this.tabData.through = { attribute };
3328
- return this;
3329
- }
3330
- /**
3331
- * Show _source and _target columns in flattened (through) view
3332
- */
3333
- showSourceTarget(value = true) {
3334
- if (!this.tabData.through) {
3335
- throw new Error(
3336
- `[TableTabConfig] showSourceTarget() requires through() to be called first for tab "${this.tabData.name}"`
3337
- );
3338
- }
3339
- this.tabData.through.showSourceTarget = value;
3340
- return this;
3341
- }
3342
3000
  /**
3343
3001
  * Continue building with a new tab
3344
3002
  */
@@ -3796,6 +3454,17 @@ var DetailViewBuilder = class {
3796
3454
  function detailView(name, label) {
3797
3455
  return new DetailViewBuilder(name, label);
3798
3456
  }
3457
+ function findProtectedTabFilterAttribute(node) {
3458
+ if (Array.isArray(node)) {
3459
+ return node.map(findProtectedTabFilterAttribute).find((attribute) => attribute !== void 0);
3460
+ }
3461
+ if (node === null || typeof node !== "object") return void 0;
3462
+ const candidate = node;
3463
+ if (candidate.attribute === "visibility" || candidate.attribute === "ownedBy") {
3464
+ return candidate.attribute;
3465
+ }
3466
+ return findProtectedTabFilterAttribute(candidate.rules) ?? findProtectedTabFilterAttribute(candidate.groups);
3467
+ }
3799
3468
  var ListViewBuilder = class {
3800
3469
  constructor(name, label) {
3801
3470
  validateViewName(name, "ListViewBuilder", {
@@ -3905,28 +3574,39 @@ var ListViewBuilder = class {
3905
3574
  combinator: this.data.defaultFilters.combinator,
3906
3575
  rules: this.data.defaultFilters.rules
3907
3576
  } : void 0,
3908
- tabs: this.data.tabs.map((tab) => ({
3909
- id: tab.id,
3910
- label: tab.label,
3911
- icon: tab.icon,
3912
- default: tab.default,
3913
- layout: tab.layout,
3914
- columns: tab.columns,
3915
- columnSizing: tab.columnSizing,
3916
- filters: tab.filters ? {
3917
- id: generateId(),
3918
- combinator: tab.filters.combinator,
3919
- rules: tab.filters.rules
3920
- } : void 0,
3921
- sorts: tab.sorts,
3922
- groupByAttribute: tab.groupByAttribute,
3923
- cardUserAttribute: tab.cardUserAttribute,
3924
- cardDateAttribute: tab.cardDateAttribute,
3925
- createMode: tab.createMode,
3926
- kanbanColumnOrder: tab.kanbanColumnOrder,
3927
- kanbanColumnVisibility: tab.kanbanColumnVisibility,
3928
- kanbanPinnedColumns: tab.kanbanPinnedColumns
3929
- }))
3577
+ tabs: this.data.tabs.map((tab) => {
3578
+ const common = {
3579
+ id: tab.id,
3580
+ label: tab.label,
3581
+ icon: tab.icon,
3582
+ default: tab.default,
3583
+ // Which records the tab scopes to — a tab-level scope, never a
3584
+ // record's own column (see the visibility notes in CLAUDE.md).
3585
+ visibility: tab.visibility,
3586
+ columns: tab.columns,
3587
+ filters: tab.filters ? {
3588
+ id: generateId(),
3589
+ combinator: tab.filters.combinator,
3590
+ rules: tab.filters.rules
3591
+ } : void 0,
3592
+ sorts: tab.sorts,
3593
+ createMode: tab.createMode
3594
+ };
3595
+ return tab.layout === "kanban" ? {
3596
+ ...common,
3597
+ layout: "kanban",
3598
+ groupByAttribute: tab.groupByAttribute,
3599
+ cardUserAttribute: tab.cardUserAttribute,
3600
+ cardDateAttribute: tab.cardDateAttribute,
3601
+ kanbanColumnOrder: tab.kanbanColumnOrder,
3602
+ kanbanColumnVisibility: tab.kanbanColumnVisibility,
3603
+ kanbanPinnedColumns: tab.kanbanPinnedColumns
3604
+ } : {
3605
+ ...common,
3606
+ layout: "table",
3607
+ columnSizing: tab.columnSizing
3608
+ };
3609
+ })
3930
3610
  };
3931
3611
  return {
3932
3612
  name: this.data.name,
@@ -3948,6 +3628,7 @@ var ListViewTabConfigBuilder = class _ListViewTabConfigBuilder {
3948
3628
  this.tabData = {
3949
3629
  id,
3950
3630
  label,
3631
+ visibility: "all",
3951
3632
  layout: "table",
3952
3633
  columns: []
3953
3634
  };
@@ -3966,6 +3647,14 @@ var ListViewTabConfigBuilder = class _ListViewTabConfigBuilder {
3966
3647
  this.tabData.default = true;
3967
3648
  return this;
3968
3649
  }
3650
+ /**
3651
+ * Set the record scope this tab reads. Defaults to `"all"` (no scope: every
3652
+ * workspace record plus the viewer's own private ones).
3653
+ */
3654
+ visibility(value) {
3655
+ this.tabData.visibility = value;
3656
+ return this;
3657
+ }
3969
3658
  /**
3970
3659
  * Set the layout to table (default)
3971
3660
  */
@@ -4059,6 +3748,11 @@ var ListViewTabConfigBuilder = class _ListViewTabConfigBuilder {
4059
3748
  * @example .filter({ combinator: "and", rules: [{ attribute: "status", operator: "is", value: "active" }] })
4060
3749
  */
4061
3750
  filter(filters) {
3751
+ const protectedAttribute = findProtectedTabFilterAttribute(filters);
3752
+ if (protectedAttribute) {
3753
+ const message = `Tab filters cannot target "${protectedAttribute}". Use .visibility("private")`;
3754
+ throw new ValidationError(message, [{ path: ["filters"], message }]);
3755
+ }
4062
3756
  this.tabData.filters = filters;
4063
3757
  return this;
4064
3758
  }
@@ -4816,7 +4510,7 @@ var SKILL_OBJECT = object({ name: "skill", label: "Skill" }).sealed().icon("spar
4816
4510
  )
4817
4511
  ).attribute(richtext({ name: "content", label: "Content" }).defaultValue(SKILL_CONTENT_TEMPLATE)).build();
4818
4512
  var SKILL_VIEW = detailView("skill-detail", "Skill").for("skill").default().sidePanel({ attributes: ["name", "description"] }).tab("content", "Content").richtext("content").titleAttribute("name").done().tab("files", "Files").documents().done().build();
4819
- var SKILL_LIST_VIEW = listView("skill-list", "Skills").for("skill").default().tab("all", "All").table().columns("name", "description").sort("name", "asc").build();
4513
+ var SKILL_LIST_VIEW = listView("skill-list", "Skills").for("skill").default().tab("workspace", "Skills").default().icon("table").visibility("workspace").table().columns("name", "description").sort("name", "asc").tab("mine", "Mes skills").icon("lock").visibility("private").table().columns("name", "description").sort("name", "asc").build();
4820
4514
  var MEMORY_OBJECT = object({ name: "memory", label: "Memory" }).sealed().icon("database").order(Number.MAX_SAFE_INTEGER).pluralLabel("Memories").labelExpression("{{ name }}").embeddingExpression("{{ name }}\n{{ description }}\n{{ content }}").attribute(text({ name: "name", label: "Name" }).maxLength(MEMORY_NAME_MAX_LENGTH).required()).attribute(
4821
4515
  text({ name: "description", label: "Description" }).multiline().maxLength(MEMORY_DESCRIPTION_MAX_LENGTH).required()
4822
4516
  ).attribute(text({ name: "content", label: "Content" }).multiline()).attribute(
@@ -4826,9 +4520,9 @@ var MEMORY_OBJECT = object({ name: "memory", label: "Memory" }).sealed().icon("d
4826
4520
  { value: "feedback", label: "Feedback" },
4827
4521
  { value: "reference", label: "Reference" }
4828
4522
  ])
4829
- ).attribute(user({ name: "owner", label: "Owner" })).attribute(relation({ name: "subjects", label: "Subjects" }).toAny().many()).attribute(relation({ name: "links", label: "Links" }).to("memory").many()).build();
4830
- var MEMORY_VIEW = detailView("memory-detail", "Memory").for("memory").default().sidePanel({ attributes: ["name", "description", "kind", "owner", "subjects", "links"] }).tab("content", "Content").form(group("content", "Content").field("content", { span: 12 })).build();
4831
- var MEMORY_LIST_VIEW = listView("memory-list", "Memories").for("memory").default().tab("all", "All").table().columns("name", "description", "kind", "owner").sort("name", "asc").build();
4523
+ ).attribute(relation({ name: "subjects", label: "Subjects" }).toAny().many()).attribute(relation({ name: "links", label: "Links" }).to("memory").many()).build();
4524
+ var MEMORY_VIEW = detailView("memory-detail", "Memory").for("memory").default().sidePanel({ attributes: ["name", "description", "kind", "subjects", "links"] }).tab("content", "Content").form(group("content", "Content").field("content", { span: 12 })).build();
4525
+ var MEMORY_LIST_VIEW = listView("memory-list", "Memories").for("memory").default().tab("workspace", "Memories").default().icon("table").visibility("workspace").table().columns("name", "kind", "description", "createdAt").sort("name", "asc").tab("mine", "Mes m\xE9moires").icon("lock").visibility("private").table().columns("name", "kind", "description", "createdAt").sort("name", "asc").build();
4832
4526
 
4833
4527
  // src/views/registry.ts
4834
4528
  function cloneViewDefinition(view) {
@@ -5033,6 +4727,7 @@ function generateDefaultDetailView(object2, options = {}) {
5033
4727
  {
5034
4728
  id: "general",
5035
4729
  label: "General",
4730
+ type: "fields",
5036
4731
  fields: sortedAttrs.map(attributeToField),
5037
4732
  order: 0
5038
4733
  }
@@ -5087,6 +4782,7 @@ function generateDefaultListView(object2, options = {}) {
5087
4782
  id: "all",
5088
4783
  label: "All",
5089
4784
  default: true,
4785
+ visibility: "workspace",
5090
4786
  layout: "table",
5091
4787
  columns
5092
4788
  }
@@ -5346,6 +5042,8 @@ var BROWSER_PREVIEW_STATUSES = ["live", "paused", "ended", "disconnected"];
5346
5042
  var LIVE_EVENT_TYPE_REGISTRY = {
5347
5043
  "record.patch": true,
5348
5044
  "record.deleted": true,
5045
+ "record.removed": true,
5046
+ "record.created": true,
5349
5047
  "view.projection.stale": true,
5350
5048
  "agent.session.patch": true,
5351
5049
  "agent.unread.patch": true,
@@ -5392,6 +5090,33 @@ var BROWSER_PREVIEW_DESCRIPTOR_KEYS = [
5392
5090
  "sequence",
5393
5091
  "updatedAt"
5394
5092
  ];
5093
+ var RECORD_REMOVED_PAYLOAD_KEYS = [
5094
+ "type",
5095
+ "objectId",
5096
+ "recordId",
5097
+ "recordVersion"
5098
+ ];
5099
+ var RECORD_CREATED_PAYLOAD_KEYS = [
5100
+ "type",
5101
+ "objectId",
5102
+ "recordId",
5103
+ "recordVersion",
5104
+ "record"
5105
+ ];
5106
+ var RECORD_LIVE_SNAPSHOT_KEYS = [
5107
+ "id",
5108
+ "objectId",
5109
+ "visibility",
5110
+ "ownedBy",
5111
+ "label",
5112
+ "values",
5113
+ "metadata",
5114
+ "createdAt",
5115
+ "updatedAt",
5116
+ "createdBy",
5117
+ "lastUpdatedBy",
5118
+ "schemaVersion"
5119
+ ];
5395
5120
  function isLiveEventType(value) {
5396
5121
  return typeof value === "string" && LIVE_EVENT_TYPES.includes(value);
5397
5122
  }
@@ -5410,6 +5135,10 @@ function isLiveEventPayloadForType(type, payload) {
5410
5135
  return isRecordPatchPayload(payload);
5411
5136
  case "record.deleted":
5412
5137
  return isRecordDeletedPayload(payload);
5138
+ case "record.removed":
5139
+ return isRecordRemovedPayload(payload);
5140
+ case "record.created":
5141
+ return isRecordCreatedPayload(payload);
5413
5142
  case "view.projection.stale":
5414
5143
  return isViewProjectionStalePayload(payload);
5415
5144
  case "agent.session.patch":
@@ -5505,6 +5234,15 @@ function isRecordPatchPayload(payload) {
5505
5234
  function isRecordDeletedPayload(payload) {
5506
5235
  return payload.type === "record.deleted" && hasString(payload, "objectId") && hasString(payload, "recordId") && hasVersion(payload, "recordVersion") && hasString(payload, "deletedAt");
5507
5236
  }
5237
+ function isRecordRemovedPayload(payload) {
5238
+ return payload.type === "record.removed" && hasOnlyKeys(payload, RECORD_REMOVED_PAYLOAD_KEYS) && hasString(payload, "objectId") && hasString(payload, "recordId") && hasVersion(payload, "recordVersion");
5239
+ }
5240
+ function isRecordLiveSnapshot(value) {
5241
+ return isRecord(value) && hasOnlyKeys(value, RECORD_LIVE_SNAPSHOT_KEYS) && hasString(value, "id") && hasString(value, "objectId") && isOneOf(value.visibility, ["workspace", "private"]) && isNullableString(value.ownedBy) && (value.visibility === "workspace" && value.ownedBy === null || value.visibility === "private" && isNonEmptyString(value.ownedBy)) && hasString(value, "label") && isRecord(value.values) && hasOptional(value, "metadata", isRecord) && hasIsoDateString(value, "createdAt") && hasIsoDateString(value, "updatedAt") && hasOptional(value, "createdBy", isString) && hasOptional(value, "lastUpdatedBy", isString) && hasVersion(value, "schemaVersion");
5242
+ }
5243
+ function isRecordCreatedPayload(payload) {
5244
+ return payload.type === "record.created" && hasOnlyKeys(payload, RECORD_CREATED_PAYLOAD_KEYS) && hasString(payload, "objectId") && hasString(payload, "recordId") && hasVersion(payload, "recordVersion") && isRecordLiveSnapshot(payload.record) && payload.record.id === payload.recordId && payload.record.objectId === payload.objectId;
5245
+ }
5508
5246
  function isViewProjectionStalePayload(payload) {
5509
5247
  return payload.type === "view.projection.stale" && hasString(payload, "viewId") && isOneOf(payload.reason, VIEW_PROJECTION_STALE_REASONS);
5510
5248
  }
@@ -6796,46 +6534,79 @@ var toDate2 = (v) => {
6796
6534
  return Number.isNaN(d.getTime()) ? null : d;
6797
6535
  };
6798
6536
  var toArr = (v) => Array.isArray(v) ? v : v == null ? [] : [v];
6799
- function relativeDateBoundary(rel) {
6800
- const ms = {
6801
- days: 864e5,
6802
- weeks: 6048e5,
6803
- months: 2592e6,
6804
- years: 31536e6
6805
- };
6806
- const offset = rel.amount * ms[rel.unit] * (rel.direction === "future" ? 1 : -1);
6807
- return new Date(Date.now() + offset);
6537
+ var compareNumbers = (v, rv, cmp) => {
6538
+ const a = toNum(v);
6539
+ const b = toNum(rv);
6540
+ return a !== null && b !== null && cmp(a, b);
6541
+ };
6542
+ var compareDates = (v, rv, cmp) => {
6543
+ const a = toDate2(v);
6544
+ const b = toDate2(rv);
6545
+ return a !== null && b !== null && cmp(a.getTime(), b.getTime());
6546
+ };
6547
+ var equalsForAttr = (v, rv, attr) => {
6548
+ if (attr.type === "number" || attr.type === "currency") {
6549
+ const a = toNum(v);
6550
+ const b = toNum(rv);
6551
+ if (a !== null && b !== null) return a === b;
6552
+ }
6553
+ return toStr(v) === toStr(rv);
6554
+ };
6555
+ function isCheckboxEquality(attributeType, value) {
6556
+ return attributeType ? attributeType === "checkbox" : typeof value === "boolean";
6808
6557
  }
6558
+ var orderingSpec = (cmp) => ({
6559
+ appliesTo: ["number", "currency", "date", "formula"],
6560
+ evaluateInMemory: (v, rv, attr) => attr.type === "date" ? compareDates(v, rv, cmp) : compareNumbers(v, rv, cmp)
6561
+ });
6809
6562
  var OPERATOR_SPECS = {
6810
- // ---- text-style ----
6563
+ // ---- equality ----
6811
6564
  is: {
6812
- appliesTo: ["text", "phone", "status", "select", "date", "formula"],
6813
- evaluateInMemory: (v, rv) => toStr(v) === toStr(rv)
6565
+ appliesTo: [
6566
+ "text",
6567
+ "phone",
6568
+ "number",
6569
+ "currency",
6570
+ "checkbox",
6571
+ "status",
6572
+ "select",
6573
+ "date",
6574
+ "user",
6575
+ "relation",
6576
+ "formula"
6577
+ ],
6578
+ evaluateInMemory: (v, rv, attr) => attr.type === "checkbox" ? v === true === (rv === true) : equalsForAttr(v, rv, attr)
6814
6579
  },
6815
6580
  is_not: {
6816
- appliesTo: ["text", "phone", "status", "select", "date", "formula"],
6817
- evaluateInMemory: (v, rv) => toStr(v) !== toStr(rv)
6581
+ appliesTo: [
6582
+ "text",
6583
+ "phone",
6584
+ "number",
6585
+ "currency",
6586
+ "status",
6587
+ "select",
6588
+ "date",
6589
+ "user",
6590
+ "relation",
6591
+ "formula"
6592
+ ],
6593
+ evaluateInMemory: (v, rv, attr) => !equalsForAttr(v, rv, attr)
6818
6594
  },
6595
+ // ---- text substring ----
6819
6596
  contains: {
6820
- appliesTo: ["text", "phone", "location", "user", "multiselect", "relation", "formula"],
6821
- evaluateInMemory: (v, rv) => {
6822
- if (Array.isArray(v)) return v.map(toStr).includes(toStr(rv));
6823
- return toStr(v).toLowerCase().includes(toStr(rv).toLowerCase());
6824
- }
6597
+ appliesTo: ["text", "phone", "formula"],
6598
+ evaluateInMemory: (v, rv) => toStr(v).toLowerCase().includes(toStr(rv).toLowerCase())
6825
6599
  },
6826
6600
  not_contains: {
6827
- appliesTo: ["text", "phone", "user", "multiselect", "relation", "formula"],
6828
- evaluateInMemory: (v, rv) => {
6829
- if (Array.isArray(v)) return !v.map(toStr).includes(toStr(rv));
6830
- return !toStr(v).toLowerCase().includes(toStr(rv).toLowerCase());
6831
- }
6601
+ appliesTo: ["text", "phone", "formula"],
6602
+ evaluateInMemory: (v, rv) => !toStr(v).toLowerCase().includes(toStr(rv).toLowerCase())
6832
6603
  },
6833
6604
  starts_with: {
6834
- appliesTo: ["text", "formula"],
6605
+ appliesTo: ["text", "phone"],
6835
6606
  evaluateInMemory: (v, rv) => toStr(v).toLowerCase().startsWith(toStr(rv).toLowerCase())
6836
6607
  },
6837
6608
  ends_with: {
6838
- appliesTo: ["text", "formula"],
6609
+ appliesTo: ["text"],
6839
6610
  evaluateInMemory: (v, rv) => toStr(v).toLowerCase().endsWith(toStr(rv).toLowerCase())
6840
6611
  },
6841
6612
  is_empty: {
@@ -6876,100 +6647,22 @@ var OPERATOR_SPECS = {
6876
6647
  ],
6877
6648
  evaluateInMemory: (v) => !isEmpty(v)
6878
6649
  },
6879
- // ---- numeric ----
6880
- eq: {
6881
- appliesTo: ["number", "currency", "formula"],
6882
- evaluateInMemory: (v, rv) => toNum(v) === toNum(rv)
6883
- },
6884
- neq: {
6885
- appliesTo: ["number", "currency", "formula"],
6886
- evaluateInMemory: (v, rv) => toNum(v) !== toNum(rv)
6887
- },
6888
- lt: {
6889
- appliesTo: ["number", "currency", "formula"],
6890
- evaluateInMemory: (v, rv) => {
6891
- const a = toNum(v);
6892
- const b = toNum(rv);
6893
- return a !== null && b !== null && a < b;
6894
- }
6895
- },
6896
- gt: {
6897
- appliesTo: ["number", "currency", "formula"],
6898
- evaluateInMemory: (v, rv) => {
6899
- const a = toNum(v);
6900
- const b = toNum(rv);
6901
- return a !== null && b !== null && a > b;
6902
- }
6903
- },
6904
- lte: {
6905
- appliesTo: ["number", "currency", "formula"],
6906
- evaluateInMemory: (v, rv) => {
6907
- const a = toNum(v);
6908
- const b = toNum(rv);
6909
- return a !== null && b !== null && a <= b;
6910
- }
6911
- },
6912
- gte: {
6913
- appliesTo: ["number", "currency", "formula"],
6914
- evaluateInMemory: (v, rv) => {
6915
- const a = toNum(v);
6916
- const b = toNum(rv);
6917
- return a !== null && b !== null && a >= b;
6918
- }
6919
- },
6920
- // ---- checkbox ----
6921
- is_checked: {
6922
- appliesTo: ["checkbox"],
6923
- evaluateInMemory: (v) => v === true
6924
- },
6925
- is_not_checked: {
6926
- appliesTo: ["checkbox"],
6927
- evaluateInMemory: (v) => v !== true
6928
- },
6929
- // ---- date ----
6930
- before: {
6931
- appliesTo: ["date"],
6932
- evaluateInMemory: (v, rv) => {
6933
- const a = toDate2(v);
6934
- const b = toDate2(rv);
6935
- return a !== null && b !== null && a < b;
6936
- }
6937
- },
6938
- after: {
6939
- appliesTo: ["date"],
6940
- evaluateInMemory: (v, rv) => {
6941
- const a = toDate2(v);
6942
- const b = toDate2(rv);
6943
- return a !== null && b !== null && a > b;
6944
- }
6945
- },
6946
- on_or_before: {
6947
- appliesTo: ["date"],
6948
- evaluateInMemory: (v, rv) => {
6949
- const a = toDate2(v);
6950
- const b = toDate2(rv);
6951
- return a !== null && b !== null && a <= b;
6952
- }
6953
- },
6954
- on_or_after: {
6955
- appliesTo: ["date"],
6956
- evaluateInMemory: (v, rv) => {
6957
- const a = toDate2(v);
6958
- const b = toDate2(rv);
6959
- return a !== null && b !== null && a >= b;
6960
- }
6961
- },
6650
+ // ---- ordering (numeric on number/currency/formula, chronological on date) ----
6651
+ less_than: orderingSpec((a, b) => a < b),
6652
+ greater_than: orderingSpec((a, b) => a > b),
6653
+ less_or_equal: orderingSpec((a, b) => a <= b),
6654
+ greater_or_equal: orderingSpec((a, b) => a >= b),
6655
+ // ---- date-only ----
6962
6656
  is_within: {
6963
6657
  appliesTo: ["date"],
6964
6658
  evaluateInMemory: (v, rv) => {
6965
6659
  const d = toDate2(v);
6966
- if (!d) return false;
6967
- const rel = rv;
6968
- const boundary = relativeDateBoundary(rel);
6969
- return rel.direction === "future" ? d >= /* @__PURE__ */ new Date() && d <= boundary : d >= boundary && d <= /* @__PURE__ */ new Date();
6660
+ const bounds = resolveIsWithinBounds(rv);
6661
+ if (!(d && bounds)) return false;
6662
+ return d.getTime() >= bounds.startMs && d.getTime() < bounds.endMs;
6970
6663
  }
6971
6664
  },
6972
- day_month_eq: {
6665
+ on_day_month: {
6973
6666
  appliesTo: ["date"],
6974
6667
  evaluateInMemory: (v, rv) => {
6975
6668
  const d = toDate2(v);
@@ -6978,9 +6671,9 @@ var OPERATOR_SPECS = {
6978
6671
  return d.getMonth() + 1 === rule.month && d.getDate() === rule.day;
6979
6672
  }
6980
6673
  },
6981
- // ---- select multi-value ----
6674
+ // ---- set membership ----
6982
6675
  any_of: {
6983
- appliesTo: ["status", "select", "relation"],
6676
+ appliesTo: ["status", "select", "multiselect", "user", "relation"],
6984
6677
  evaluateInMemory: (v, rv) => {
6985
6678
  const ruleArr = toArr(rv).map(toStr);
6986
6679
  const valArr = toArr(v).map(toStr);
@@ -6988,7 +6681,7 @@ var OPERATOR_SPECS = {
6988
6681
  }
6989
6682
  },
6990
6683
  none_of: {
6991
- appliesTo: ["status", "select", "relation"],
6684
+ appliesTo: ["status", "select", "multiselect", "user", "relation"],
6992
6685
  evaluateInMemory: (v, rv) => {
6993
6686
  const ruleArr = toArr(rv).map(toStr);
6994
6687
  const valArr = toArr(v).map(toStr);
@@ -6997,37 +6690,34 @@ var OPERATOR_SPECS = {
6997
6690
  }
6998
6691
  };
6999
6692
 
7000
- // src/filters/evaluate.ts
7001
- function evaluateFilterState(state, values, attributes) {
7002
- if (state.rules.length === 0) return true;
7003
- const attrByName = new Map(attributes.map((a) => [a.name, a]));
7004
- const reducer = state.combinator === "or" ? "some" : "every";
7005
- return state.rules[reducer]((rule) => evaluateRule(rule, values, attrByName));
6693
+ // src/filters/extract-filter-value.ts
6694
+ function extractCurrencyFilterValue(value) {
6695
+ if (typeof value === "number") return value;
6696
+ if (value !== null && typeof value === "object" && "value" in value) {
6697
+ const inner = value.value;
6698
+ return typeof inner === "number" ? inner : null;
6699
+ }
6700
+ return null;
7006
6701
  }
7007
- function evaluateRule(rule, values, attrByName) {
7008
- const attr = attrByName.get(rule.attribute);
7009
- if (!attr) return false;
7010
- const spec = OPERATOR_SPECS[rule.operator];
7011
- if (!spec) return false;
7012
- if (!spec.appliesTo.includes(attr.type)) return false;
7013
- return spec.evaluateInMemory(values[rule.attribute], rule.value, attr);
6702
+ function extractFilterValue(value) {
6703
+ if (value === null || value === void 0) return null;
6704
+ if (typeof value === "object" && "value" in value) {
6705
+ return value.value ?? null;
6706
+ }
6707
+ return value;
7014
6708
  }
7015
6709
 
7016
6710
  // src/filters/polarity.ts
7017
6711
  var NEGATIVE_OPERATORS = /* @__PURE__ */ new Set([
7018
6712
  "is_not",
7019
6713
  "not_contains",
7020
- "neq",
7021
6714
  "none_of",
7022
- "is_not_checked",
7023
6715
  "is_empty"
7024
6716
  ]);
7025
6717
  var NEGATIVE_TO_POSITIVE = {
7026
6718
  is_not: "is",
7027
6719
  not_contains: "contains",
7028
- neq: "eq",
7029
6720
  none_of: "any_of",
7030
- is_not_checked: "is_checked",
7031
6721
  is_empty: "is_not_empty"
7032
6722
  };
7033
6723
  function getOperatorPolarity(op) {
@@ -7038,251 +6728,136 @@ function normalizeForEdgeRpc(op) {
7038
6728
  }
7039
6729
  var SINGLE_TO_MULTI = {
7040
6730
  is: "any_of",
7041
- eq: "any_of",
7042
- contains: "any_of",
7043
- is_not: "none_of",
7044
- neq: "none_of",
7045
- not_contains: "none_of"
6731
+ is_not: "none_of"
7046
6732
  };
7047
6733
  function toMultiValueOperator(op) {
7048
6734
  return SINGLE_TO_MULTI[op] ?? op;
7049
6735
  }
7050
6736
 
7051
- // src/filters/dynamic-value.ts
7052
- function isDynamicValue(value) {
7053
- return typeof value === "object" && value !== null && !Array.isArray(value) && "dynamic" in value;
7054
- }
7055
- function currentActor() {
7056
- return { dynamic: "actor", ref: "current" };
7057
- }
7058
- function today() {
7059
- return { dynamic: "date", anchor: "today" };
7060
- }
7061
- function now() {
7062
- return { dynamic: "date", anchor: "now" };
6737
+ // src/filters/evaluate.ts
6738
+ var systemAttribute = (name, type) => ({ id: `system:${name}`, name, label: name, type, system: true });
6739
+ var RECORD_SYSTEM_ATTRIBUTES = [
6740
+ ...Object.entries(SYSTEM_FILTER_ATTRIBUTE_TYPES).map(
6741
+ ([name, type]) => systemAttribute(name, type)
6742
+ )
6743
+ ];
6744
+ function evaluateRecordFilterState(state, record, attributes) {
6745
+ const physical = record;
6746
+ return evaluateFilterState(
6747
+ state,
6748
+ {
6749
+ ...record.values,
6750
+ id: record.id,
6751
+ objectId: record.objectId,
6752
+ objectName: physical.objectName,
6753
+ tenantId: physical.tenantId,
6754
+ label: record.label,
6755
+ createdAt: record.createdAt,
6756
+ updatedAt: record.updatedAt,
6757
+ createdBy: record.createdBy,
6758
+ lastUpdatedBy: record.lastUpdatedBy,
6759
+ deletedAt: record.deletedAt,
6760
+ deletedBy: record.deletedBy,
6761
+ visibility: record.visibility,
6762
+ ownedBy: record.ownedBy
6763
+ },
6764
+ [...attributes, ...RECORD_SYSTEM_ATTRIBUTES]
6765
+ );
7063
6766
  }
7064
-
7065
- // src/filters/normalize-operator.ts
7066
- var SYNONYM_ALIASES = {
7067
- // equality
7068
- equals: "is",
7069
- equal: "is",
7070
- "==": "is",
7071
- "=": "is",
7072
- notEqual: "is_not",
7073
- isNot: "is_not",
7074
- "!=": "is_not",
7075
- "<>": "is_not",
7076
- // set
7077
- in: "any_of",
7078
- isAnyOf: "any_of",
7079
- oneOf: "any_of",
7080
- notIn: "none_of",
7081
- not_in: "none_of",
7082
- isNoneOf: "none_of",
7083
- notOneOf: "none_of",
7084
- // text
7085
- startsWith: "starts_with",
7086
- beginsWith: "starts_with",
7087
- endsWith: "ends_with",
7088
- doesNotContain: "not_contains",
7089
- notContain: "not_contains",
7090
- // nullity
7091
- isEmpty: "is_empty",
7092
- isNotEmpty: "is_not_empty",
7093
- // checkbox
7094
- isChecked: "is_checked",
7095
- isUnchecked: "is_not_checked"
7096
- };
7097
- var CROSS_TYPE_CONVERSIONS = {
7098
- date: {
7099
- gte: "on_or_after",
7100
- lte: "on_or_before",
7101
- gt: "after",
7102
- lt: "before",
7103
- eq: "is",
7104
- neq: "is_not"
7105
- },
7106
- number: { is: "eq", is_not: "neq" },
7107
- currency: { is: "eq", is_not: "neq" },
7108
- text: { eq: "is", neq: "is_not" },
7109
- phone: { eq: "is", neq: "is_not" },
7110
- select: { eq: "is", neq: "is_not" },
7111
- status: { eq: "is", neq: "is_not" },
7112
- multiselect: { eq: "contains", neq: "not_contains" },
7113
- relation: { eq: "is", neq: "is_not" },
7114
- user: { eq: "is", neq: "is_not" },
7115
- document: { eq: "is", neq: "is_not" },
7116
- file: { eq: "is", neq: "is_not" },
7117
- checkbox: { eq: "is_checked", neq: "is_not_checked", is: "is_checked", is_not: "is_not_checked" }
7118
- };
7119
- function normalizeOperator(rawOp, effectiveType) {
7120
- const synonymed = SYNONYM_ALIASES[rawOp] ?? rawOp;
7121
- const typeMap = CROSS_TYPE_CONVERSIONS[effectiveType];
7122
- return typeMap?.[synonymed] ?? synonymed;
6767
+ function evaluateFilterState(state, values, attributes) {
6768
+ if (state.rules.length === 0) return true;
6769
+ const attrByName = new Map(attributes.map((a) => [a.name, a]));
6770
+ const reducer = state.combinator === "or" ? "some" : "every";
6771
+ return state.rules[reducer]((rule) => evaluateRule(rule, values, attrByName));
7123
6772
  }
7124
-
7125
- // src/filters/validation.ts
7126
- var REFERENCE_TYPES = /* @__PURE__ */ new Set(["relation", "document", "user"]);
7127
- var ID_LIKE_OPERATORS = [
7128
- "eq",
7129
- "neq",
7130
- "is",
7131
- "is_not",
7132
- "any_of",
7133
- "none_of",
7134
- "is_empty",
7135
- "is_not_empty"
7136
- ];
7137
- var SYSTEM_FILTER_OPERATORS = {
7138
- // Identifier columns (uuid)
7139
- id: ID_LIKE_OPERATORS,
7140
- objectId: ID_LIKE_OPERATORS,
7141
- tenantId: ID_LIKE_OPERATORS,
7142
- // Free-form text columns share their counterpart's operator set
7143
- label: OPERATORS_BY_TYPE.text,
7144
- // Date columns
7145
- createdAt: OPERATORS_BY_TYPE.date,
7146
- updatedAt: OPERATORS_BY_TYPE.date,
7147
- deletedAt: OPERATORS_BY_TYPE.date,
7148
- // User columns (uuid → actor identity)
7149
- createdBy: OPERATORS_BY_TYPE.user,
7150
- lastUpdatedBy: OPERATORS_BY_TYPE.user
7151
- };
7152
- var SYSTEM_ATTRIBUTE_TYPES = {
7153
- id: "id",
7154
- objectId: "id",
7155
- tenantId: "id",
7156
- label: "text",
7157
- createdAt: "date",
7158
- updatedAt: "date",
7159
- deletedAt: "date",
7160
- createdBy: "user",
7161
- lastUpdatedBy: "user"
7162
- };
7163
- function assertOperatorForType(operator, type, context) {
7164
- const normalized = normalizeOperator(operator, type);
7165
- const ops = OPERATORS_BY_TYPE[type];
7166
- if (!ops?.includes(normalized)) {
7167
- const validList = ops?.length ? ops.join(", ") : "(no operators registered for this type)";
7168
- const summary = `Operator "${operator}" is not valid for ${context} type "${type}". Valid operators: ${validList}.`;
7169
- throw new ValidationError(summary, [
7170
- {
7171
- path: ["operator"],
7172
- message: summary
7173
- }
7174
- ]);
7175
- }
7176
- return normalized;
7177
- }
7178
- var RELATIVE_DATE_UNITS = /* @__PURE__ */ new Set(["days", "weeks", "months", "years"]);
7179
- var RELATIVE_DATE_DIRECTIONS = /* @__PURE__ */ new Set(["past", "future"]);
7180
- function assertRelativeDateValue(rule) {
7181
- if (rule.operator !== "is_within") return;
7182
- const v = rule.value;
7183
- const valid = typeof v === "object" && v !== null && typeof v.amount === "number" && Number.isFinite(v.amount) && v.amount > 0 && typeof v.unit === "string" && RELATIVE_DATE_UNITS.has(v.unit) && typeof v.direction === "string" && RELATIVE_DATE_DIRECTIONS.has(v.direction);
7184
- if (!valid) {
7185
- const m = `Operator "is_within" requires a relative-date value { amount: positive number, unit: days|weeks|months|years, direction: past|future }`;
7186
- throw new ValidationError(m, [{ path: ["value"], message: m }]);
7187
- }
7188
- }
7189
- function assertDynamicValueForAttribute(rule, attrType) {
7190
- if (!isDynamicValue(rule.value)) return;
7191
- const v = rule.value;
7192
- if (v.dynamic === "actor" && attrType !== "user") {
7193
- const m = `actor token (@me) is only valid on user attributes, not "${attrType}"`;
7194
- throw new ValidationError(m, [{ path: ["value"], message: m }]);
7195
- }
7196
- if (v.dynamic === "date" && attrType !== "date") {
7197
- const m = `date token (@today/@now) is only valid on date attributes, not "${attrType}"`;
7198
- throw new ValidationError(m, [{ path: ["value"], message: m }]);
7199
- }
7200
- }
7201
- function validateQualifiedRule(rule, context) {
7202
- const rootAttr = context.attributes.find((a) => a.name === rule.attribute);
7203
- const systemOps = SYSTEM_FILTER_OPERATORS[rule.attribute];
7204
- if (!(rootAttr || systemOps)) {
7205
- throw new ValidationError(`Unknown attribute: ${rule.attribute}`, [
7206
- { path: ["attribute"], message: `Unknown attribute: ${rule.attribute}` }
7207
- ]);
7208
- }
7209
- if (rule.quantifier !== void 0 && !rule.property) {
7210
- const m = `quantifier is only valid on qualified edge rules (set "property")`;
7211
- throw new ValidationError(m, [{ path: ["quantifier"], message: m }]);
7212
- }
7213
- if (!rootAttr) {
7214
- if (rule.property) {
7215
- throw new ValidationError(`Cannot qualify system attribute "${rule.attribute}"`, [
7216
- { path: ["property"], message: `"${rule.attribute}" is a system column, not a reference` }
7217
- ]);
7218
- }
7219
- const effectiveType = SYSTEM_ATTRIBUTE_TYPES[rule.attribute] ?? "id";
7220
- const normalizedOperator = normalizeOperator(
7221
- rule.operator,
7222
- effectiveType
7223
- );
7224
- if (!systemOps.includes(normalizedOperator)) {
7225
- const summary = `Operator "${rule.operator}" is not valid for system attribute "${rule.attribute}". Valid operators: ${systemOps.join(", ")}.`;
7226
- throw new ValidationError(summary, [{ path: ["operator"], message: summary }]);
7227
- }
7228
- rule.operator = normalizedOperator;
7229
- assertRelativeDateValue(rule);
7230
- return;
7231
- }
7232
- if (!rule.property) {
7233
- assertDynamicValueForAttribute(rule, rootAttr.type);
7234
- const ops = getAttributeFilterOperators(rootAttr);
7235
- const normalizedOperator = normalizeOperator(
7236
- rule.operator,
7237
- rootAttr.type
7238
- );
7239
- if (!ops.includes(normalizedOperator)) {
7240
- const validList = ops.length ? ops.join(", ") : "(not filterable)";
7241
- const summary = `Operator "${rule.operator}" is not valid for attribute "${rootAttr.name}". Valid operators: ${validList}.`;
7242
- throw new ValidationError(summary, [{ path: ["operator"], message: summary }]);
7243
- }
7244
- rule.operator = normalizedOperator;
7245
- assertRelativeDateValue(rule);
7246
- return;
7247
- }
7248
- if (!REFERENCE_TYPES.has(rootAttr.type)) {
7249
- throw new ValidationError(`Cannot qualify ${rootAttr.type} attribute "${rule.attribute}"`, [
7250
- { path: ["property"], message: `Attribute "${rule.attribute}" is not a reference type` }
7251
- ]);
7252
- }
7253
- const propSchema = rootAttr.properties;
7254
- if (!propSchema) {
7255
- throw new ValidationError(`Attribute "${rule.attribute}" has no qualifyWith schema`, [
7256
- { path: ["property"], message: `"${rule.attribute}" has no qualifyWith` }
7257
- ]);
7258
- }
7259
- const propDef = propSchema.definitions.find((p) => p.name === rule.property);
7260
- if (!propDef) {
7261
- throw new ValidationError(
7262
- `Property "${rule.property}" not defined on "${rule.attribute}".qualifyWith()`,
7263
- [{ path: ["property"], message: `Unknown property: ${rule.property}` }]
6773
+ function evaluateRule(rule, values, attrByName) {
6774
+ const attr = attrByName.get(rule.attribute);
6775
+ if (!attr) return false;
6776
+ if (rule.property) {
6777
+ const property = resolvePropertyDefinitions(attr).find(
6778
+ (definition) => definition.name === rule.property
7264
6779
  );
6780
+ if (!property) return false;
6781
+ const positiveOperator = normalizeForEdgeRpc(rule.operator);
6782
+ const propertySpec = OPERATOR_SPECS[positiveOperator];
6783
+ if (!propertySpec?.appliesTo.includes(property.type)) return false;
6784
+ const rootValue = values[rule.attribute];
6785
+ const references = Array.isArray(rootValue) ? rootValue : rootValue == null ? [] : [rootValue];
6786
+ const matches = references.some((reference) => {
6787
+ if (typeof reference !== "object" || reference === null) return false;
6788
+ const props = reference.props;
6789
+ if (typeof props !== "object" || props === null) return false;
6790
+ return evaluateNormalizedComparands(
6791
+ propertySpec,
6792
+ property.type,
6793
+ positiveOperator,
6794
+ props[rule.property],
6795
+ rule.value,
6796
+ property
6797
+ );
6798
+ });
6799
+ return (rule.quantifier ?? getOperatorPolarity(rule.operator)) === "none" ? !matches : matches;
7265
6800
  }
7266
- rule.operator = assertOperatorForType(rule.operator, propDef.type, "property");
7267
- assertRelativeDateValue(rule);
7268
- }
7269
-
7270
- // src/filters/extract-filter-value.ts
7271
- function extractCurrencyFilterValue(value) {
7272
- if (typeof value === "number") return value;
7273
- if (value !== null && typeof value === "object" && "value" in value) {
7274
- const inner = value.value;
7275
- return typeof inner === "number" ? inner : null;
7276
- }
7277
- return null;
6801
+ const spec = OPERATOR_SPECS[rule.operator];
6802
+ if (!spec) return false;
6803
+ if (!spec.appliesTo.includes(attr.type)) return false;
6804
+ const rawValue = values[rule.attribute];
6805
+ const value = attr.type === "relation" || attr.type === "document" || attr.type === "user" ? normalizeReferenceIds(rawValue) : rawValue;
6806
+ return evaluateNormalizedComparands(spec, attr.type, rule.operator, value, rule.value, attr);
6807
+ }
6808
+ function evaluateNormalizedComparands(spec, type, operator, storedValue, ruleValue, attribute) {
6809
+ const [normalizedStored, normalizedRule] = normalizeOperatorComparands(
6810
+ type,
6811
+ operator,
6812
+ storedValue,
6813
+ ruleValue
6814
+ );
6815
+ if (type === "phone" && normalizedRule === "" && operator === "contains") return false;
6816
+ if (type === "phone" && normalizedRule === "" && operator === "not_contains") return true;
6817
+ return spec.evaluateInMemory(normalizedStored, normalizedRule, attribute);
6818
+ }
6819
+ function normalizeOperatorComparands(type, operator, storedValue, ruleValue) {
6820
+ if (type === "date" && (operator === "is" || operator === "is_not")) {
6821
+ return [normalizeUtcCalendarDay(storedValue), normalizeUtcCalendarDay(ruleValue)];
6822
+ }
6823
+ if (type === "phone") return normalizePhoneComparands(storedValue, ruleValue);
6824
+ return [normalizeComparableValue(type, storedValue), normalizeComparableValue(type, ruleValue)];
6825
+ }
6826
+ function normalizeUtcCalendarDay(value) {
6827
+ if (value instanceof Date)
6828
+ return Number.isNaN(value.getTime()) ? null : value.toISOString().slice(0, 10);
6829
+ if (typeof value !== "string" || value === "") return null;
6830
+ if (/^\d{4}-\d{2}-\d{2}$/.test(value)) return value;
6831
+ const date2 = new Date(value);
6832
+ return Number.isNaN(date2.getTime()) ? null : date2.toISOString().slice(0, 10);
6833
+ }
6834
+ function normalizePhoneComparands(stored, rule) {
6835
+ const rulePhone = typeof rule === "object" && rule !== null ? rule : { };
6836
+ const ruleCountry = typeof rulePhone.countryCode === "string" ? rulePhone.countryCode : void 0;
6837
+ const normalizeOne = (value) => {
6838
+ const phone2 = typeof value === "object" && value !== null ? value : { phoneNumber: value };
6839
+ if (typeof phone2.phoneNumber !== "string") return null;
6840
+ if (!ruleCountry) return normalizeCountrylessPhoneNumber(phone2.phoneNumber);
6841
+ const country = typeof phone2.countryCode === "string" ? phone2.countryCode : ruleCountry;
6842
+ return `${country}:${normalizePhoneNumber(phone2.phoneNumber, country)}`;
6843
+ };
6844
+ return [normalizeOne(stored), normalizeOne(rule)];
7278
6845
  }
7279
- function extractFilterValue(value) {
7280
- if (value === null || value === void 0) return null;
7281
- if (typeof value === "object" && "value" in value) {
7282
- return value.value ?? null;
6846
+ function normalizeComparableValue(type, value) {
6847
+ if (type === "currency") return extractCurrencyFilterValue(value);
6848
+ if (type === "date") {
6849
+ if (value instanceof Date) return Number.isNaN(value.getTime()) ? null : value.toISOString();
6850
+ return value;
7283
6851
  }
7284
6852
  return value;
7285
6853
  }
6854
+ function normalizeReferenceIds(value) {
6855
+ const normalizeOne = (candidate) => {
6856
+ if (typeof candidate !== "object" || candidate === null) return candidate;
6857
+ return candidate.id;
6858
+ };
6859
+ return Array.isArray(value) ? value.map(normalizeOne) : normalizeOne(value);
6860
+ }
7286
6861
 
7287
6862
  // src/connectors/types.ts
7288
6863
  var CONNECTOR_CALLBACK_PARAM = {
@@ -7322,6 +6897,23 @@ function canonicalStringify(value) {
7322
6897
  return encode(value) ?? "null";
7323
6898
  }
7324
6899
 
6900
+ // src/utils/attribute-defaults.ts
6901
+ var TODAY_DEFAULT = "today";
6902
+ function dateInTimezone(date2, timezone) {
6903
+ return new Intl.DateTimeFormat("en-CA", {
6904
+ timeZone: timezone,
6905
+ year: "numeric",
6906
+ month: "2-digit",
6907
+ day: "2-digit"
6908
+ }).format(date2);
6909
+ }
6910
+ function resolveAttributeDefaultValue(attribute, ctx) {
6911
+ if (!("defaultValue" in attribute)) return void 0;
6912
+ const { defaultValue } = attribute;
6913
+ if (attribute.type !== "date" || defaultValue !== TODAY_DEFAULT) return defaultValue;
6914
+ return attribute.includeTime ? ctx.now.toISOString() : dateInTimezone(ctx.now, ctx.timezone);
6915
+ }
6916
+
7325
6917
  // src/utils/view-sync-payload.ts
7326
6918
  function viewSyncPayload(view) {
7327
6919
  return {
@@ -7334,4 +6926,418 @@ function viewSyncPayload(view) {
7334
6926
  };
7335
6927
  }
7336
6928
 
7337
- export { ALLOWED_PROPERTY_TYPES, ALL_ACTIONS, ALL_SYSTEM_RESOURCES, ATTRIBUTE_FILTER_OPERATORS, AUDIT_ACTIONS, AUDIT_RESOURCE_TYPES, ActivityTabConfig, AgentBuilder, BEHAVIOR_PROPERTIES, BROWSER_PREVIEW_STATUSES, COMPUTED_FUNCTIONS, COMPUTED_FUNCTION_METADATA, COMPUTED_FUNCTION_NAMES, CONNECTOR_CALLBACK_PARAM, CROSS_TYPE_CONVERSIONS, ComputedFormulaCompileError, CustomTabConfig, DB_COLUMN_FIELDS, DEFAULT_AGENT_EXECUTION_CONFIG, DEFAULT_ROLES, DEFAULT_ROLE_DESCRIPTIONS, DEFAULT_ROLE_LABELS, DEFAULT_ROLE_PERMISSIONS, DOCUMENT_SYSTEM_ATTRIBUTES, DetailViewBuilder, DocumentsTabConfig, EMPTY_VALUE_PLACEHOLDER, EmailsTabConfig, FORM_FORBIDDEN_ATTRIBUTE_TYPES, FlagRegistry, FlagService, FormBuilder, FormRegistry, FormRowBuilder, FormStepBuilder, GroupBuilder, IDENTITY_PROPERTIES, LIVE_EVENT_TYPES, LIVE_STREAM_START_CURSOR, ListViewBuilder, ListViewTabConfigBuilder, MAX_PRESET_DEPTH, MEMORY_LIST_VIEW, MEMORY_OBJECT, MEMORY_VIEW, NOTIFICATION_INBOX_STATES, NOTIFICATION_KINDS, NOTIFICATION_PRIORITIES, NOTIFICATION_SENSITIVITIES, NOTIFICATION_TYPES_V1, NOTIFICATION_TYPE_AGENT_QUESTION_REQUESTED, NOTIFICATION_TYPE_AGENT_SESSION_COMPLETED, NOTIFICATION_TYPE_AGENT_SESSION_FAILED, NOTIFICATION_TYPE_AGENT_SESSION_TIMEOUT, NOTIFICATION_TYPE_AGENT_SESSION_WAITING_HUMAN, NOTIFICATION_TYPE_AGENT_TASK_ASSIGNED, NOTIFICATION_WORK_STATES, NO_VALUE_OPERATORS, NoopGeocodingAdapter, OPERATORS_BY_TYPE, OPERATOR_SPECS, ObjectBuilder, PRESENTATION_PROPERTIES, QUALIFIED_SEPARATOR, RELATION_TARGET_ANY, RESERVED_ATTRIBUTE_NAMES, RESERVED_OBJECT_NAMES, RelationGroupBuilder, RichtextTabConfig, SKILL_LIST_VIEW, SKILL_OBJECT, SKILL_VIEW, STANDARD_SCHEMA_VENDOR, SYNONYM_ALIASES, SYSTEM_ATTRIBUTES, SYSTEM_ATTRIBUTE_I18N_KEYS, SYSTEM_FIELD_NAMES, SYSTEM_RESOURCES, SYSTEM_RESOURCE_LABELS, TabBuilder, TableTabConfig, USER_STATUSES, accessLevelToActions, actionsToAccessLevel, agent, applyPipes, applyRelationProps, assertAcyclicComputedDependencies, assertLiveStreamCursor, booleanFlag, buildPropertySchema, buildQualifiedAttribute, canonicalStringify, checkbox, compareLiveStreamCursors, compileComputedFormula, compileRollupAttribute, createFlagRegistry, createFlagService, createStandardSchemaProps, currency, currentActor, date, dateValueStart, detailView, document, evaluateComputedAst, evaluateComputedFormula, evaluateComputedFormulaWithResult, evaluateFilterState, extractAttributeNames, extractCurrencyFilterValue, extractFilterValue, extractValueRefs, flagRegistry, form, formRegistry, formatAttributeValue, formatComputedResult, formatLocationValue, formula, generateDefaultDetailView, generateDefaultListView, getActiveTab, getAttributeCapabilities, getAttributeFilterOperators, getErrorMessage, getLiveProtocolPayloadChannel, getOperatorPolarity, getRollupFilterOperators2 as getRollupFilterOperators, getSlotFieldTargets, getSystemAttributeI18nKey, getSystemAttributeList, getUserDisplayName, group, hasOptions, inferInverseCardinality, inferRollupReturnType, isAttributeFilterable, isAttributeGroupable, isAttributeKanbanGroupable, isAttributeSearchable, isAttributeSortable2 as isAttributeSortable, isBilateralRelation, isComputedFunctionName, isDateRangeValue, isDefaultRole, isDetailView, isDocumentAttribute, isDynamicValue, isEmptyObject, isFieldGroup, isFormDefinition, isFormFieldsRow, isFormFreeFieldRef, isFormHeadingRow, isFormSeparatorRow, isFormSlotFieldRef, isFormTextRow, isLabelExpression, isListView, isLiveErrorPayload, isLiveEventEnvelope, isLiveEventPayload, isLiveEventPayloadForType, isLiveEventType, isLiveGapPayload, isLiveReplayCompletePayload, isLiveStreamCursor, isManagedSystemAttribute, isNoValueOperator, isNotEmpty, isPlainRecord, isRelationGroup, isStandardSchema, isUniversalRelation, jsonFlag, listView, liveChannelKey, location, matchesMime, multiselect, normalizeDateValue, normalizeForEdgeRpc, normalizeOperator, now, number, numberFlag, object, parseLiveChannelKey, parseLiveSubscribePayload, parseLiveUnsubscribePayload, parseQualifiedAttribute, phone, registry, relation, relationGroup, renderLabelExpression, resetViewToDefault, resolvePropertyDefinitions, richtext, rollup, rollupToFormulaExpression, select, status, stringFlag, text, toMultiValueOperator, toUndefinedIfEmpty, today, user, validateAttributeName, validateQualifiedRule, viewRegistry, viewSyncPayload };
6929
+ // src/types/schema-plan.ts
6930
+ function hasDestructiveEntries(plan) {
6931
+ const { attributeRemovals, objectRemovals, renames } = plan.destructive;
6932
+ return attributeRemovals.length > 0 || objectRemovals.length > 0 || renames.length > 0;
6933
+ }
6934
+ var SCHEMA_PLAN_LIMITS = {
6935
+ objectAdditions: 20,
6936
+ totalMutations: 500,
6937
+ serializedBytes: 512 * 1024
6938
+ };
6939
+ function errorMessage(error) {
6940
+ return error instanceof Error ? error.message : String(error);
6941
+ }
6942
+ var attributeTypeSchema = z.enum([
6943
+ "text",
6944
+ "richtext",
6945
+ "number",
6946
+ "checkbox",
6947
+ "date",
6948
+ "phone",
6949
+ "currency",
6950
+ "status",
6951
+ "location",
6952
+ "select",
6953
+ "multiselect",
6954
+ "user",
6955
+ "relation",
6956
+ "formula",
6957
+ "rollup",
6958
+ "document"
6959
+ ]).describe(
6960
+ 'The attribute\'s data type. Determines which keys `config` accepts and requires: `status`/`select`/`multiselect` need a non-empty `options` array (each `status` option carrying its own `group`); `relation` needs `targets` (non-empty) and `cardinality` ("one" or "many"); `formula` needs `expression` and `returnType`; `rollup` needs `targetAttribute` and `function`. Every other type accepts only the shared presentation keys (`placeholder`, `defaultValue`, `icon`, ...) plus a few type-specific optionals (e.g. `number.decimals`, `date.dateFormat`). An attribute\'s type can never be changed later through this tool \u2014 only through a code migration \u2014 so pick it correctly now.'
6961
+ );
6962
+ var attributeNameSchema = z.string().min(1).superRefine((name, ctx) => {
6963
+ try {
6964
+ validateAttributeName(name);
6965
+ } catch (error) {
6966
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: errorMessage(error) });
6967
+ }
6968
+ }).describe(
6969
+ 'The attribute\'s machine name \u2014 the record\'s field key, and what `{{ name }}` refers to in a labelExpression. Must be a valid identifier: starts with a letter or underscore, then only letters/digits/underscores ("montantHt", "first_name", "FIRST_NAME" are valid; "first-name", "first name", "123name" are not). Max 63 characters. Cannot be a name reserved by the record shape itself (id, createdAt, updatedAt, createdBy, lastUpdatedBy, objectId, label, embeddingText, values, metadata, deletedAt, deletedBy, schemaVersion).'
6970
+ );
6971
+ var objectNameSchema = z.string().min(1).superRefine((name, ctx) => {
6972
+ if (RESERVED_OBJECT_NAMES.includes(name)) {
6973
+ ctx.addIssue({
6974
+ code: z.ZodIssueCode.custom,
6975
+ message: `"${name}" is a reserved object name (${RESERVED_OBJECT_NAMES.join(", ")}) and cannot be used for a new object.`
6976
+ });
6977
+ }
6978
+ try {
6979
+ validateObjectName(name);
6980
+ } catch (error) {
6981
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: errorMessage(error) });
6982
+ }
6983
+ }).describe(
6984
+ `The new object's machine name: kebab-case slug, lowercase letters/digits/hyphens only, starting with a letter ("products", "user-profiles", "order-items" are valid; "Products", "userProfiles", "user_profiles" are not). Max 63 characters. Cannot be a name the platform reserves for its own system objects, and cannot already exist.`
6985
+ );
6986
+ function withConfigCheck(schema) {
6987
+ return schema.superRefine((attribute, ctx) => {
6988
+ try {
6989
+ const parsedConfig = parseAttributeConfigForCreate(attribute.type, {
6990
+ ...attribute.config ?? {},
6991
+ description: attribute.description
6992
+ });
6993
+ const unknownKeys = Object.keys(attribute.config ?? {}).filter(
6994
+ (key) => !Object.hasOwn(parsedConfig, key)
6995
+ );
6996
+ if (unknownKeys.length > 0) {
6997
+ ctx.addIssue({
6998
+ code: "unrecognized_keys",
6999
+ keys: unknownKeys,
7000
+ path: ["config"],
7001
+ message: `Unrecognized attribute config key${unknownKeys.length === 1 ? "" : "s"}: ${unknownKeys.join(", ")}`
7002
+ });
7003
+ }
7004
+ } catch (error) {
7005
+ if (error instanceof ValidationError) {
7006
+ for (const issue of error.errors) {
7007
+ ctx.addIssue({
7008
+ code: z.ZodIssueCode.custom,
7009
+ path: [
7010
+ "config",
7011
+ ...issue.path.map((segment) => /^\d+$/.test(segment) ? Number(segment) : segment)
7012
+ ],
7013
+ message: `Config for type "${attribute.type}" is invalid or incomplete: ${issue.message}`
7014
+ });
7015
+ }
7016
+ return;
7017
+ }
7018
+ ctx.addIssue({
7019
+ code: z.ZodIssueCode.custom,
7020
+ path: ["config"],
7021
+ message: `Config for type "${attribute.type}" is invalid or incomplete: ${errorMessage(error)}`
7022
+ });
7023
+ }
7024
+ });
7025
+ }
7026
+ var plannedAttributeBaseSchema = z.object({
7027
+ objectName: z.string().min(1).describe(
7028
+ "Name of the existing (or, elsewhere in the same plan, newly created) object this attribute is added to. Ignored for an attribute declared inline in `additive.objects[].attributes` \u2014 there the parent object's own `name` is used instead."
7029
+ ),
7030
+ name: attributeNameSchema,
7031
+ label: z.string().min(1).max(128).describe("Human-readable display label shown in the UI. 1-128 characters, cannot be empty."),
7032
+ type: attributeTypeSchema,
7033
+ config: z.record(z.string(), z.unknown()).optional().describe(
7034
+ 'Type-specific configuration; required keys depend on `type` (see `type`\'s description). Shared optional keys on every type: `placeholder`, `defaultValue`, `icon`, `order`, `hidden`, `archived`, `deprecated`, `metadata`. Per-type keys: `text` \u2014 `multiline`, `minLength`, `maxLength`, `pattern`, `format` ("email"|"url"|"slug"); `number` \u2014 `renderAs` ("number"|"rating"), `min`, `max`, `unit`, `decimals`; `date` \u2014 `dateFormat`, `minDate`, `maxDate`, `includeTime`, `endDate`, `timeFormat` ("12h"|"24h"); `phone` \u2014 `defaultCountryCode` (3-letter); `currency` \u2014 `defaultCurrency`, `allowedCurrencies`, `allowNegative`; `status`/`select`/`multiselect` \u2014 `options` (REQUIRED, non-empty array of `{ value, label, color }`, unique `value`s; for `status` every OPTION also carries `group` as idle|in_progress|finished \u2014 `group` belongs on each option, never on `config` itself; select/multiselect accept `renderAs: "badges"`); `location` \u2014 `granularity`, `defaultCountry`, `allowedCountries`; `user` \u2014 `types` ("user"|"agent"), `multiple`; `relation` \u2014 `targets` (REQUIRED, non-empty array of `{ object }`) and `cardinality` (REQUIRED, "one"|"many"); `formula` \u2014 `expression` (REQUIRED formula string) and `returnType` (REQUIRED); `rollup` \u2014 `targetAttribute` (REQUIRED) and `function` (REQUIRED, e.g. "sum"|"avg"|"count"); `document` \u2014 `properties`, `accepts`, `maxFileSize`. Omit entirely for `richtext`/`checkbox`, which take no type-specific keys.'
7035
+ ),
7036
+ required: z.boolean().optional().describe(
7037
+ "Whether the attribute must have a value on every record. Defaults to false (optional)."
7038
+ ),
7039
+ description: z.string().optional().describe("Help text shown under the field in the UI. Not the same as the plan's `summary`.")
7040
+ }).strict();
7041
+ var plannedAttributeSchema = withConfigCheck(plannedAttributeBaseSchema);
7042
+ var plannedInlineAttributeSchema = withConfigCheck(
7043
+ plannedAttributeBaseSchema.omit({ objectName: true })
7044
+ );
7045
+ var plannedObjectSchema = z.object({
7046
+ name: objectNameSchema,
7047
+ label: z.string().min(1).describe('Human-readable singular display label (e.g. "Devis").'),
7048
+ pluralLabel: z.string().optional().describe(
7049
+ 'Human-readable plural display label (e.g. "Devis"/"Invoices"). Defaults from `label` if omitted.'
7050
+ ),
7051
+ description: z.string().optional().describe("Help text describing what this object represents."),
7052
+ icon: iconNameSchema.describe(
7053
+ "Required icon name for the object. Must be a catalogue value \u2014 call `search_icons` and use a name it returns verbatim. A name that is not in the catalogue is rejected without any hint as to what would have worked, so never guess one."
7054
+ ),
7055
+ labelExpression: labelExpressionSchema.describe(
7056
+ 'Template used to render a human-readable label for every record of this object \u2014 e.g. shown in relations, search results, and breadcrumbs. MUST contain at least one `{{ attributeName }}` interpolation referencing an attribute this object will actually have (either declared in this same `attributes` array, or an existing attribute if this is an update) \u2014 a plain string with no `{{ }}` at all (e.g. "Devis") is rejected. Interpolations cannot be empty (`{{ }}` is rejected) and only these pipes are allowed: UPPER, LOWER, capitalize, trim, prefix:"...", suffix:"...", wrap:"..." "...", default:"...". `{{ a || b }}` falls back to `b` when `a` is empty. Examples: "{{ firstName }} {{ lastName }}", "{{ numero | UPPER }}", "{{ name || reference }}".'
7057
+ ),
7058
+ // Inline attributes get the SAME validation as attributes added to an
7059
+ // existing object, minus `objectName` which the parent supplies. Anything
7060
+ // weaker would let an agent slip a typeless attribute into a new object
7061
+ // while the strict path above rejects the identical mistake.
7062
+ attributes: z.array(plannedInlineAttributeSchema).default([]).describe(
7063
+ "Attributes to create on this new object, inline. Same rules as a standalone entry in `additive.attributes`, minus `objectName` (implied by this object). At least one attribute referenced by `labelExpression` should be included here."
7064
+ )
7065
+ }).strict();
7066
+ var destructiveSchema = z.object({
7067
+ attributeRemovals: z.array(
7068
+ z.object({
7069
+ objectName: z.string().min(1).describe("Object the attribute is removed from."),
7070
+ attributeName: z.string().min(1).describe(
7071
+ "Attribute to delete, together with every record's stored value for it. Must not be a system (code-declared) attribute, and must not be referenced by the object's own `labelExpression` or `embeddingExpression` \u2014 update those first."
7072
+ )
7073
+ }).strict()
7074
+ ).default([]).describe(
7075
+ "Attributes to permanently delete. Irreversible: record values for the attribute are purged."
7076
+ ),
7077
+ objectRemovals: z.array(
7078
+ z.object({
7079
+ objectName: z.string().min(1).describe(
7080
+ "Object to delete entirely, together with all its records. Must not be a system (code-declared) object, and must not still be targeted by a `relation` attribute on another object \u2014 retarget or remove that relation first."
7081
+ )
7082
+ }).strict()
7083
+ ).default([]).describe("Objects to permanently delete, records included. Irreversible."),
7084
+ renames: z.array(
7085
+ z.object({
7086
+ objectName: z.string().min(1).describe("Object the renamed attribute belongs to."),
7087
+ from: z.string().min(1).describe(
7088
+ "Current attribute name. Must already exist and not be a system attribute."
7089
+ ),
7090
+ to: attributeNameSchema.describe(
7091
+ "New attribute name \u2014 same identifier rules as any attribute `name` (see `name` on a planned attribute), and must not collide with another name already on the object, including one added elsewhere in this same plan."
7092
+ )
7093
+ }).strict()
7094
+ ).default([]).describe(
7095
+ "Attribute renames. Every reference to the old name (labelExpression, views, formulas) must be updated separately \u2014 a rename does not follow references automatically."
7096
+ )
7097
+ }).strict().default({ attributeRemovals: [], objectRemovals: [], renames: [] });
7098
+ var planSummarySchema = z.string().min(1).describe(
7099
+ "One or two plain-language sentences describing the change and why, shown to the human who approves or rejects the plan \u2014 this is the only free-text context they see before deciding. If `destructive` is non-empty, say plainly what will be lost (e.g. 'deletes the \"ancienMontant\" column and its data on every devis'). Do not restate the raw plan \u2014 explain intent."
7100
+ );
7101
+ var CANONICAL_CONFIG_DESCRIPTION = "The COMPLETE config this view should end up with \u2014 not a patch. Copy the baseline returned by get_default_view and edit it, preserving every tab and setting you are not changing: anything you omit is dropped. To change the columns shown, set `tabs[].columns` (an array of attribute names) \u2014 there is no top-level `columns` on either view type. For a detail view's side panel, set `sidePanel.attributes`. Every attribute name listed must already exist on the object, or be created earlier in this same plan. ONE EXCEPTION to omit-is-dropped: a tab with `type: \"custom\"` renders a component belonging to the application, which you cannot describe or recreate. Copy every such tab through from the baseline exactly as it came, `name`, `component` and `props` untouched \u2014 dropping one, inventing one, or altering any of those three is rejected rather than applied (`name` is the tab's address in links, not its wording). Its `label` and `icon` you may change.";
7102
+ var BASELINE_TOKEN_DESCRIPTION = "Opaque token returned by get_default_view alongside the baseline you edited. REQUIRED when the object already exists \u2014 it proves you authored against the baseline that is still current. Must be OMITTED when this plan creates the object, which has no baseline yet.";
7103
+ var viewTargetObjectNameSchema = z.string().min(1).describe(
7104
+ "Name of the object whose default view of this type is replaced. Not a view name \u2014 a plan can only replace an object's deterministic default view, never create a view or target a non-default one."
7105
+ );
7106
+ var proposedDefaultViewTargetSchema = z.discriminatedUnion("viewType", [
7107
+ z.object({
7108
+ objectName: viewTargetObjectNameSchema,
7109
+ viewType: z.literal("list").describe("Targets the object's default list view (the grid)."),
7110
+ canonicalConfig: listViewConfigSchema.describe(CANONICAL_CONFIG_DESCRIPTION),
7111
+ baselineToken: z.string().min(1).optional().describe(BASELINE_TOKEN_DESCRIPTION)
7112
+ }).strict(),
7113
+ z.object({
7114
+ objectName: viewTargetObjectNameSchema,
7115
+ viewType: z.literal("detail").describe("Targets the object's default detail view (the single-record view)."),
7116
+ canonicalConfig: detailViewConfigSchema.describe(CANONICAL_CONFIG_DESCRIPTION),
7117
+ baselineToken: z.string().min(1).optional().describe(BASELINE_TOKEN_DESCRIPTION)
7118
+ }).strict()
7119
+ ]);
7120
+ var canonicalHashSchema = z.string().regex(/^[0-9a-f]{64}$/, "Expected a lowercase SHA-256 hash");
7121
+ var persistedBaselineFields = {
7122
+ baseConfigHash: canonicalHashSchema.nullable(),
7123
+ targetConfigHash: canonicalHashSchema,
7124
+ baselineOrigin: z.enum(["persisted", "generated", "absent"])
7125
+ };
7126
+ var persistedDefaultViewTargetSchema = z.discriminatedUnion("viewType", [
7127
+ z.object({
7128
+ objectName: z.string().min(1),
7129
+ viewType: z.literal("list"),
7130
+ canonicalConfig: listViewConfigSchema,
7131
+ ...persistedBaselineFields
7132
+ }).strict(),
7133
+ z.object({
7134
+ objectName: z.string().min(1),
7135
+ viewType: z.literal("detail"),
7136
+ canonicalConfig: detailViewConfigSchema,
7137
+ ...persistedBaselineFields
7138
+ }).strict()
7139
+ ]).superRefine((target, ctx) => {
7140
+ const requiresHash = target.baselineOrigin !== "absent";
7141
+ if (requiresHash === (target.baseConfigHash !== null)) return;
7142
+ ctx.addIssue({
7143
+ code: "custom",
7144
+ path: ["baseConfigHash"],
7145
+ message: requiresHash ? `A ${target.baselineOrigin} baseline requires baseConfigHash` : "An absent baseline requires baseConfigHash to be null"
7146
+ });
7147
+ });
7148
+ function buildAdditiveSchema(viewTargetSchema) {
7149
+ return z.object({
7150
+ objects: z.array(plannedObjectSchema).default([]).describe("New objects to create, with their attributes inline."),
7151
+ attributes: z.array(plannedAttributeSchema).default([]).describe("Attributes to add to existing or same-plan objects."),
7152
+ viewUpdates: z.array(viewTargetSchema).default([]).describe("Complete target configs for deterministic default views; never view names.")
7153
+ }).strict().default({ objects: [], attributes: [], viewUpdates: [] });
7154
+ }
7155
+ function findJsonSafetyIssue(value, path = [], activeObjects = /* @__PURE__ */ new WeakSet()) {
7156
+ if (value === null || typeof value === "string" || typeof value === "boolean") return null;
7157
+ if (typeof value === "number") {
7158
+ if (!Number.isFinite(value)) {
7159
+ return { path, message: "Plan input contains a non-finite number" };
7160
+ }
7161
+ return null;
7162
+ }
7163
+ if (typeof value !== "object") {
7164
+ return { path, message: "Plan input must contain only JSON-safe values" };
7165
+ }
7166
+ if (activeObjects.has(value)) {
7167
+ return { path, message: "Plan input cannot contain circular references" };
7168
+ }
7169
+ if (Array.isArray(value)) {
7170
+ activeObjects.add(value);
7171
+ for (const key of Reflect.ownKeys(value)) {
7172
+ if (key === "length") continue;
7173
+ if (typeof key === "symbol" || !/^(0|[1-9]\d*)$/.test(key)) {
7174
+ activeObjects.delete(value);
7175
+ return {
7176
+ path: [...path, key],
7177
+ message: "Plan input arrays cannot contain non-index JSON properties"
7178
+ };
7179
+ }
7180
+ }
7181
+ for (let index = 0; index < value.length; index++) {
7182
+ if (!Object.hasOwn(value, index)) {
7183
+ activeObjects.delete(value);
7184
+ return {
7185
+ path: [...path, index],
7186
+ message: "Plan input cannot contain sparse arrays"
7187
+ };
7188
+ }
7189
+ const issue = findJsonSafetyIssue(value[index], [...path, index], activeObjects);
7190
+ if (issue) {
7191
+ activeObjects.delete(value);
7192
+ return issue;
7193
+ }
7194
+ }
7195
+ activeObjects.delete(value);
7196
+ return null;
7197
+ }
7198
+ const prototype = Object.getPrototypeOf(value);
7199
+ if (prototype !== Object.prototype && prototype !== null) {
7200
+ return { path, message: "Plan input must contain only plain JSON objects" };
7201
+ }
7202
+ activeObjects.add(value);
7203
+ const record = value;
7204
+ const keys = Reflect.ownKeys(record);
7205
+ for (const key of keys) {
7206
+ const descriptor = Object.getOwnPropertyDescriptor(record, key);
7207
+ if (typeof key === "symbol" || !(descriptor?.enumerable && "value" in descriptor)) {
7208
+ activeObjects.delete(value);
7209
+ return {
7210
+ path: [...path, key],
7211
+ message: "Plan input objects must contain enumerable JSON data properties only"
7212
+ };
7213
+ }
7214
+ }
7215
+ for (const key of keys.sort()) {
7216
+ const issue = findJsonSafetyIssue(record[key], [...path, key], activeObjects);
7217
+ if (issue) {
7218
+ activeObjects.delete(value);
7219
+ return issue;
7220
+ }
7221
+ }
7222
+ activeObjects.delete(value);
7223
+ return null;
7224
+ }
7225
+ function mutationPaths(plan) {
7226
+ const paths = [];
7227
+ plan.additive.objects.forEach((object2, objectIndex) => {
7228
+ paths.push(["additive", "objects", objectIndex]);
7229
+ object2.attributes.forEach((_attribute, attributeIndex) => {
7230
+ paths.push(["additive", "objects", objectIndex, "attributes", attributeIndex]);
7231
+ });
7232
+ });
7233
+ plan.additive.attributes.forEach((_attribute, index) => {
7234
+ paths.push(["additive", "attributes", index]);
7235
+ });
7236
+ plan.additive.viewUpdates.forEach((_target, index) => {
7237
+ paths.push(["additive", "viewUpdates", index]);
7238
+ });
7239
+ plan.destructive.attributeRemovals.forEach((_removal, index) => {
7240
+ paths.push(["destructive", "attributeRemovals", index]);
7241
+ });
7242
+ plan.destructive.objectRemovals.forEach((_removal, index) => {
7243
+ paths.push(["destructive", "objectRemovals", index]);
7244
+ });
7245
+ plan.destructive.renames.forEach((_rename, index) => {
7246
+ paths.push(["destructive", "renames", index]);
7247
+ });
7248
+ return paths;
7249
+ }
7250
+ function addPlanLimitIssues(plan, ctx) {
7251
+ if (plan.additive.objects.length > SCHEMA_PLAN_LIMITS.objectAdditions) {
7252
+ ctx.addIssue({
7253
+ code: "too_big",
7254
+ origin: "array",
7255
+ maximum: SCHEMA_PLAN_LIMITS.objectAdditions,
7256
+ inclusive: true,
7257
+ path: ["additive", "objects", SCHEMA_PLAN_LIMITS.objectAdditions],
7258
+ message: `A schema plan can add at most ${SCHEMA_PLAN_LIMITS.objectAdditions} objects`
7259
+ });
7260
+ }
7261
+ const paths = mutationPaths(plan);
7262
+ if (paths.length > SCHEMA_PLAN_LIMITS.totalMutations) {
7263
+ ctx.addIssue({
7264
+ code: "too_big",
7265
+ origin: "array",
7266
+ maximum: SCHEMA_PLAN_LIMITS.totalMutations,
7267
+ inclusive: true,
7268
+ path: paths[SCHEMA_PLAN_LIMITS.totalMutations],
7269
+ message: `A schema plan can contain at most ${SCHEMA_PLAN_LIMITS.totalMutations} mutations; received ${paths.length}`
7270
+ });
7271
+ }
7272
+ }
7273
+ function boundSerializedPlanInput(input, ctx) {
7274
+ const jsonSafetyIssue = findJsonSafetyIssue(input);
7275
+ if (jsonSafetyIssue) {
7276
+ ctx.addIssue({
7277
+ code: "custom",
7278
+ path: jsonSafetyIssue.path,
7279
+ message: jsonSafetyIssue.message
7280
+ });
7281
+ return z.NEVER;
7282
+ }
7283
+ const serializedBytes = new TextEncoder().encode(canonicalStringify(input)).byteLength;
7284
+ if (serializedBytes > SCHEMA_PLAN_LIMITS.serializedBytes) {
7285
+ ctx.addIssue({
7286
+ code: "too_big",
7287
+ origin: "string",
7288
+ maximum: SCHEMA_PLAN_LIMITS.serializedBytes,
7289
+ inclusive: true,
7290
+ path: [],
7291
+ message: `A schema plan can serialize to at most ${SCHEMA_PLAN_LIMITS.serializedBytes} UTF-8 bytes; received ${serializedBytes}`
7292
+ });
7293
+ return z.NEVER;
7294
+ }
7295
+ return input;
7296
+ }
7297
+ var proposedAdditiveSchema = buildAdditiveSchema(proposedDefaultViewTargetSchema);
7298
+ var persistedAdditiveSchema = buildAdditiveSchema(persistedDefaultViewTargetSchema);
7299
+ var structuralSchemaPlanSchema = z.object({
7300
+ schemaPlanVersion: z.literal(2).describe("Required proposal contract version."),
7301
+ summary: planSummarySchema,
7302
+ additive: proposedAdditiveSchema,
7303
+ destructive: destructiveSchema
7304
+ }).strict().superRefine((plan, ctx) => {
7305
+ const newObjectNames = new Set(plan.additive.objects.map((object2) => object2.name));
7306
+ plan.additive.viewUpdates.forEach((target, index) => {
7307
+ const path = ["additive", "viewUpdates", index, "baselineToken"];
7308
+ if (newObjectNames.has(target.objectName)) {
7309
+ if (target.baselineToken !== void 0) {
7310
+ ctx.addIssue({
7311
+ code: "custom",
7312
+ path,
7313
+ message: "A view target for an object added by this plan must not include baselineToken"
7314
+ });
7315
+ }
7316
+ return;
7317
+ }
7318
+ if (target.baselineToken === void 0) {
7319
+ ctx.addIssue({
7320
+ code: "custom",
7321
+ path,
7322
+ message: "A view target for an existing object requires baselineToken"
7323
+ });
7324
+ }
7325
+ });
7326
+ addPlanLimitIssues(plan, ctx);
7327
+ });
7328
+ var schemaPlanSchema = Object.assign(
7329
+ z.preprocess(boundSerializedPlanInput, structuralSchemaPlanSchema),
7330
+ { shape: structuralSchemaPlanSchema.shape }
7331
+ );
7332
+ var structuralPersistedSchemaPlanSchema = z.object({
7333
+ schemaPlanVersion: z.literal(2),
7334
+ summary: planSummarySchema,
7335
+ additive: persistedAdditiveSchema,
7336
+ destructive: destructiveSchema
7337
+ }).strict().superRefine(addPlanLimitIssues);
7338
+ var persistedSchemaPlanSchema = z.preprocess(
7339
+ boundSerializedPlanInput,
7340
+ structuralPersistedSchemaPlanSchema
7341
+ );
7342
+
7343
+ export { ALLOWED_PROPERTY_TYPES, ALL_ACTIONS, ALL_SYSTEM_RESOURCES, AUDIT_ACTIONS, AUDIT_RESOURCE_TYPES, ActivityTabConfig, AgentBuilder, BEHAVIOR_PROPERTIES, BROWSER_PREVIEW_STATUSES, BYTE_UNIT_LABELS, COMPUTED_FUNCTIONS, COMPUTED_FUNCTION_METADATA, COMPUTED_FUNCTION_NAMES, CONNECTOR_CALLBACK_PARAM, ComputedFormulaCompileError, CustomTabConfig, DB_COLUMN_FIELDS, DEFAULT_AGENT_EXECUTION_CONFIG, DEFAULT_APPROVAL_POLICY, DEFAULT_ROLES, DEFAULT_ROLE_DESCRIPTIONS, DEFAULT_ROLE_LABELS, DEFAULT_ROLE_PERMISSIONS, DOCUMENT_SYSTEM_ATTRIBUTES, DetailViewBuilder, DocumentsTabConfig, EMPTY_VALUE_PLACEHOLDER, ESTIMATED_COUNT_CAP, EmailsTabConfig, FORM_FORBIDDEN_ATTRIBUTE_TYPES, FlagRegistry, FlagService, FormBuilder, FormRegistry, FormRowBuilder, FormStepBuilder, GroupBuilder, IDENTITY_PROPERTIES, LIVE_EVENT_TYPES, LIVE_STREAM_START_CURSOR, ListViewBuilder, ListViewTabConfigBuilder, MAX_PRESET_DEPTH, MAX_TODOS, MAX_TODO_DESCRIPTION_CHARS, MAX_TODO_ID_CHARS, MAX_TODO_RESULT_CHARS, MEMORY_LIST_VIEW, MEMORY_OBJECT, MEMORY_VIEW, NOTIFICATION_INBOX_STATES, NOTIFICATION_KINDS, NOTIFICATION_PRIORITIES, NOTIFICATION_SENSITIVITIES, NOTIFICATION_TYPES_V1, NOTIFICATION_TYPE_AGENT_QUESTION_REQUESTED, NOTIFICATION_TYPE_AGENT_SESSION_COMPLETED, NOTIFICATION_TYPE_AGENT_SESSION_FAILED, NOTIFICATION_TYPE_AGENT_SESSION_TIMEOUT, NOTIFICATION_TYPE_AGENT_SESSION_WAITING_HUMAN, NOTIFICATION_TYPE_AGENT_TASK_ASSIGNED, NOTIFICATION_WORK_STATES, NoopGeocodingAdapter, OPERATOR_SPECS, ObjectBuilder, PRESENTATION_PROPERTIES, QUALIFIED_SEPARATOR, RECORD_CREATOR_ROOT_ACTOR_METADATA_KEY, RELATION_TARGET_ANY, RelationGroupBuilder, RichtextTabConfig, SCHEMA_PLAN_LIMITS, SESSION_TERMINAL_STATUSES, SKILL_LIST_VIEW, SKILL_OBJECT, SKILL_VIEW, STANDARD_SCHEMA_VENDOR, SYSTEM_RESOURCES, SYSTEM_RESOURCE_LABELS, TODAY_DEFAULT, TODO_PLAN_STATUSES, TODO_STATUSES, TabBuilder, TableTabConfig, USER_STATUSES, accessLevelToActions, actionsToAccessLevel, agent, agentDisplayName, applyPipes, applyRelationProps, assertAcyclicComputedDependencies, assertLiveStreamCursor, booleanFlag, buildPropertySchema, buildQualifiedAttribute, canonicalStringify, checkbox, compareLiveStreamCursors, compileComputedFormula, compileRollupAttribute, computeByteMagnitude, createFlagRegistry, createFlagService, createStandardSchemaProps, currency, date, dateInTimezone, dateValueStart, destructiveSchema, detailView, document, evaluateComputedAst, evaluateComputedFormula, evaluateComputedFormulaWithResult, evaluateFilterState, evaluateRecordFilterState, extractAttributeNames, extractCurrencyFilterValue, extractFilterValue, extractValueRefs, flagRegistry, form, formRegistry, formatAttributeValue, formatByteSize, formatComputedResult, formatLocationValue, formula, generateDefaultDetailView, generateDefaultListView, getActiveTab, getErrorMessage, getLiveProtocolPayloadChannel, getOperatorPolarity, getRecordCreatorPrincipalId, getSlotFieldTargets, getUserDisplayName, group, hasDestructiveEntries, hasOptions, inferInverseCardinality, inferRollupReturnType, isAttributeSortable2 as isAttributeSortable, isBilateralRelation, isCheckboxEquality, isComputedFunctionName, isDateRangeValue, isDefaultRole, isDetailView, isDocumentAttribute, isEmptyObject, isFieldGroup, isFormDefinition, isFormFieldsRow, isFormFreeFieldRef, isFormHeadingRow, isFormSeparatorRow, isFormSlotFieldRef, isFormTextRow, isLabelExpression, isListView, isLiveErrorPayload, isLiveEventEnvelope, isLiveEventPayload, isLiveEventPayloadForType, isLiveEventType, isLiveGapPayload, isLiveReplayCompletePayload, isLiveStreamCursor, isNotEmpty, isPlainRecord, isRelationGroup, isStandardSchema, isTerminalSessionStatus, isUniversalRelation, jsonFlag, listView, liveChannelKey, location, matchesAccepts, multiselect, normalizeDateValue, normalizeForEdgeRpc, number, numberFlag, object, parseLiveChannelKey, parseLiveSubscribePayload, parseLiveUnsubscribePayload, parseQualifiedAttribute, persistedDefaultViewTargetSchema, persistedSchemaPlanSchema, phone, plannedAttributeSchema, plannedInlineAttributeSchema, plannedObjectSchema, proposedDefaultViewTargetSchema, registry, relation, relationGroup, renderLabelExpression, resetViewToDefault, resolveAttributeDefaultValue, resolvePropertyDefinitions, richtext, rollup, rollupToFormulaExpression, schemaPlanSchema, select, status, stringFlag, text, toMultiValueOperator, toUndefinedIfEmpty, user, validateAttributeName, validateLabelExpression, validateObjectName, viewRegistry, viewStateKey, viewSyncPayload };