@stndrds/schema 1.0.0-alpha.282 → 1.0.0-alpha.285

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 (81) hide show
  1. package/dist/all-DanoPxKr.d.ts +879 -0
  2. package/dist/all-bG_ha0VV.d.mts +879 -0
  3. package/dist/{attributes-CU871AfG.d.ts → attributes-CNYwg_Nr.d.ts} +3 -2
  4. package/dist/{attributes-DoiGyNFk.d.mts → attributes-CWPLbp7c.d.mts} +3 -2
  5. package/dist/capabilities.d.mts +146 -0
  6. package/dist/capabilities.d.ts +146 -0
  7. package/dist/capabilities.js +77 -0
  8. package/dist/capabilities.mjs +70 -0
  9. package/dist/{chunk-R34LOMT7.mjs → chunk-5OBQRDRM.mjs} +3 -3
  10. package/dist/{chunk-QGRYOIHT.mjs → chunk-AGRAFDGU.mjs} +40 -14
  11. package/dist/{chunk-DIMTNM3F.js → chunk-BOICAZHR.js} +5 -4
  12. package/dist/{chunk-V4MZOTLV.js → chunk-I3EYILYO.js} +5 -5
  13. package/dist/{chunk-LBGLB443.js → chunk-K6ET4CXP.js} +3 -3
  14. package/dist/{chunk-PLTLAMWJ.mjs → chunk-PNOWKRH2.mjs} +2 -2
  15. package/dist/{chunk-EFSS7PGC.mjs → chunk-R57T4UDX.mjs} +1 -1
  16. package/dist/{chunk-HOVUEYEQ.mjs → chunk-RUO25ERR.mjs} +4 -0
  17. package/dist/{chunk-L4KLYMUI.js → chunk-V26R64A4.js} +4 -0
  18. package/dist/{chunk-KIMECN6D.js → chunk-YZ5RCMIQ.js} +83 -46
  19. package/dist/exceptions.d.mts +6 -2
  20. package/dist/exceptions.d.ts +6 -2
  21. package/dist/exceptions.js +39 -39
  22. package/dist/exceptions.mjs +1 -1
  23. package/dist/{helpers-BNr-Dppk.d.ts → helpers-CXkVwpsl.d.ts} +3 -3
  24. package/dist/{helpers-CfEOUBmB.d.mts → helpers-Dul_r9rJ.d.mts} +3 -3
  25. package/dist/{index-D9XBjFnu.d.mts → index-Ca-MzQuU.d.mts} +8 -3
  26. package/dist/{index-Br7koyHF.d.ts → index-Ns6KGfrZ.d.ts} +8 -3
  27. package/dist/index.d.mts +1120 -206
  28. package/dist/index.d.ts +1120 -206
  29. package/dist/index.js +1184 -359
  30. package/dist/index.mjs +868 -118
  31. package/dist/{migrations-BGWgXHXb.d.ts → migrations-DaFneOfx.d.ts} +1 -1
  32. package/dist/{migrations-C-GN1xx_.d.mts → migrations-fRvadl6i.d.mts} +1 -1
  33. package/dist/{objects-BRypaBpi.d.mts → objects-CDwMSnqv.d.mts} +2 -2
  34. package/dist/{objects-BiOMwzLL.d.ts → objects-DJv6WrDE.d.ts} +2 -2
  35. package/dist/{types-80c2rOUZ.d.mts → types-CVYiFc69.d.mts} +1 -1
  36. package/dist/{types-DqYz8Iv_.d.ts → types-NGEww_ln.d.ts} +1 -1
  37. package/dist/utils.js +8 -8
  38. package/dist/utils.mjs +2 -2
  39. package/dist/validation/all.d.mts +7 -7
  40. package/dist/validation/all.d.ts +7 -7
  41. package/dist/validation/all.js +46 -46
  42. package/dist/validation/all.mjs +5 -5
  43. package/dist/validation/complex/currency.d.mts +2 -2
  44. package/dist/validation/complex/currency.d.ts +2 -2
  45. package/dist/validation/complex/location.d.mts +2 -2
  46. package/dist/validation/complex/location.d.ts +2 -2
  47. package/dist/validation/complex/phone.d.mts +2 -2
  48. package/dist/validation/complex/phone.d.ts +2 -2
  49. package/dist/validation/complex/relation.d.mts +2 -2
  50. package/dist/validation/complex/relation.d.ts +2 -2
  51. package/dist/validation/complex/richtext.d.mts +2 -2
  52. package/dist/validation/complex/richtext.d.ts +2 -2
  53. package/dist/validation/complex/select.d.mts +2 -2
  54. package/dist/validation/complex/select.d.ts +2 -2
  55. package/dist/validation/complex/user.d.mts +2 -2
  56. package/dist/validation/complex/user.d.ts +2 -2
  57. package/dist/validation/computed/formula.d.mts +2 -2
  58. package/dist/validation/computed/formula.d.ts +2 -2
  59. package/dist/validation/computed/rollup.d.mts +2 -2
  60. package/dist/validation/computed/rollup.d.ts +2 -2
  61. package/dist/validation/config/index.d.mts +4 -4
  62. package/dist/validation/config/index.d.ts +4 -4
  63. package/dist/validation/config/index.js +15 -11
  64. package/dist/validation/config/index.mjs +2 -2
  65. package/dist/validation/core/index.d.mts +3 -3
  66. package/dist/validation/core/index.d.ts +3 -3
  67. package/dist/validation/object/index.d.mts +5 -5
  68. package/dist/validation/object/index.d.ts +5 -5
  69. package/dist/validation/object/index.js +15 -15
  70. package/dist/validation/object/index.mjs +3 -3
  71. package/dist/validation/primitives/checkbox.d.mts +2 -2
  72. package/dist/validation/primitives/checkbox.d.ts +2 -2
  73. package/dist/validation/primitives/date.d.mts +2 -2
  74. package/dist/validation/primitives/date.d.ts +2 -2
  75. package/dist/validation/primitives/number.d.mts +2 -2
  76. package/dist/validation/primitives/number.d.ts +2 -2
  77. package/dist/validation/primitives/text.d.mts +2 -2
  78. package/dist/validation/primitives/text.d.ts +2 -2
  79. package/package.json +10 -5
  80. package/dist/all-C3EaFLCU.d.ts +0 -472
  81. package/dist/all-CQMswOrw.d.mts +0 -472
package/dist/index.mjs CHANGED
@@ -1,26 +1,26 @@
1
- import { canonicalStringify, generateId } from './chunk-EFSS7PGC.mjs';
2
- export { asTenantId, asUserId, canonicalStringify, deepEqual, generateId, indexBy } from './chunk-EFSS7PGC.mjs';
3
- import { SYSTEM_FILTER_ATTRIBUTE_TYPES, RESERVED_OBJECT_NAMES, listViewConfigSchema, detailViewConfigSchema, LIST_VIEW_TAB_VISIBILITIES, RESERVED_ATTRIBUTE_NAMES, isAttributeSortable, getAttributeCapabilities, resolveIsWithinBounds, normalizeForEdgeRpc, getOperatorPolarity, extractCurrencyFilterValue } from './chunk-QGRYOIHT.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, canonicalizeFilterValue, collectQualifiedRuleIssues, currentActor, detailTabSchema, detailViewConfigSchema, extractCurrencyFilterValue, extractFilterValue, getAttributeCapabilities, getAttributeFilterOperators, getOperatorPolarity, getRollupFilterOperators, getSystemAttributeI18nKey, getSystemAttributeList, inverseSourceSchema, isAttributeFilterable, isAttributeGroupable, isAttributeKanbanGroupable, isAttributeSearchable, isDynamicValue, isManagedSystemAttribute, isNoValueOperator, isRelativeDateValue, isSetMembershipOperator, listViewConfigSchema, listViewTabSchema, normalizeFilterRule, normalizeForEdgeRpc, normalizeOperator, now, parseResourceVisibility, parseViewConfig, relationSourceSchema, resolveEffectiveFilterType, resolveIsWithinBounds, resolveUtcDayBounds, tableSourceSchema, toMultiValueOperator, toUtcDayString, today, validateQualifiedRule, viewConfigByTypeSchema, viewTypeSchema } from './chunk-QGRYOIHT.mjs';
5
- import { iconNameSchema, parseAttributeConfigForCreate, parseComputedFormula } from './chunk-R34LOMT7.mjs';
6
- export { ComputedFormulaParseError, SCHEMA_LIMITS, colorIdSchema, iconNameSchema, multiselectOptionWriteSchema, parseAttributeConfig, parseAttributeConfigForCreate, parseAttributeConfigForUpdate, parseComputedFormula, selectOptionWriteSchema, statusGroupSchema, statusOptionWriteSchema } from './chunk-R34LOMT7.mjs';
7
- import { createObjectValidator, createAttributeValidator, isNullishOrEmptyString } from './chunk-PLTLAMWJ.mjs';
8
- export { createFormAttributeValidator, isNullishOrEmptyString, isValuePresent, rejectUnknownAttributesOrThrow, validateDraft, validateDraftOrThrow, validateObject, validateObjectOrThrow } from './chunk-PLTLAMWJ.mjs';
1
+ import { canonicalStringify, generateId } from './chunk-R57T4UDX.mjs';
2
+ export { asTenantId, asUserId, canonicalStringify, deepEqual, generateId, indexBy } from './chunk-R57T4UDX.mjs';
3
+ import { RESERVED_ATTRIBUTE_NAMES, SYSTEM_FILTER_ATTRIBUTE_TYPES, RESERVED_OBJECT_NAMES, listViewConfigSchema, detailViewConfigSchema, detailTabDraftSchema, groupWriteSchema, fieldSlotSchema, sortsSchema, filterStateSchema, columnsSchema, tableSourceSchema, listViewTabSchema, LIST_VIEW_TAB_VISIBILITIES, filterGroupSchema, isAttributeSortable, getAttributeCapabilities, resolveIsWithinBounds, normalizeForEdgeRpc, getOperatorPolarity, extractCurrencyFilterValue, LIST_TAB_KANBAN_KEYS, LIST_TAB_TABLE_KEYS } from './chunk-AGRAFDGU.mjs';
4
+ export { ATTRIBUTE_FILTER_OPERATORS, LIST_TAB_KANBAN_KEYS, LIST_TAB_TABLE_KEYS, 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, canonicalizeFilterValue, collectQualifiedRuleIssues, columnsSchema, currentActor, detailTabDraftSchema, detailTabSchema, detailViewConfigSchema, extractCurrencyFilterValue, extractFilterValue, fieldSchema, fieldShape, fieldSlotSchema, filterGroupSchema, filterStateSchema, getAttributeCapabilities, getAttributeFilterOperators, getOperatorPolarity, getRollupFilterOperators, getSystemAttributeI18nKey, getSystemAttributeList, groupWriteSchema, inverseSourceSchema, isAttributeFilterable, isAttributeGroupable, isAttributeKanbanGroupable, isAttributeSearchable, isDynamicValue, isManagedSystemAttribute, isNoValueOperator, isRelativeDateValue, isSetMembershipOperator, listViewConfigSchema, listViewTabSchema, normalizeFilterRule, normalizeForEdgeRpc, normalizeOperator, now, parseResourceVisibility, parseViewConfig, relationSourceSchema, resolveEffectiveFilterType, resolveIsWithinBounds, resolveUtcDayBounds, sortsSchema, tableSourceSchema, toMultiValueOperator, toUtcDayString, today, validateQualifiedRule, viewConfigByTypeSchema, viewTypeSchema } from './chunk-AGRAFDGU.mjs';
5
+ import { createObjectValidator, createAttributeValidator, validateAttribute, isNullishOrEmptyString } from './chunk-PNOWKRH2.mjs';
6
+ export { createFormAttributeValidator, isNullishOrEmptyString, isValuePresent, rejectUnknownAttributesOrThrow, validateDraft, validateDraftOrThrow, validateObject, validateObjectOrThrow } from './chunk-PNOWKRH2.mjs';
7
+ import './chunk-GO6LQADH.mjs';
9
8
  import './chunk-QVLQPW3O.mjs';
10
9
  import './chunk-ZDQ5AP26.mjs';
11
10
  import './chunk-LV3FEUKU.mjs';
12
11
  import './chunk-UXAHLSWC.mjs';
13
12
  import './chunk-NS63SPNN.mjs';
13
+ import { iconNameSchema, parseAttributeConfigForCreate, parseComputedFormula, getAttributeConfigWriteSchema } from './chunk-5OBQRDRM.mjs';
14
+ export { ComputedFormulaParseError, SCHEMA_LIMITS, colorIdSchema, iconNameSchema, multiselectOptionWriteSchema, parseAttributeConfig, parseAttributeConfigForCreate, parseAttributeConfigForUpdate, parseComputedFormula, selectOptionWriteSchema, statusGroupSchema, statusOptionWriteSchema } from './chunk-5OBQRDRM.mjs';
14
15
  export { createCheckboxValidator } from './chunk-OSSGN43B.mjs';
15
16
  export { createDateValidator } from './chunk-Q44QKLN4.mjs';
16
17
  export { createNumberValidator } from './chunk-UANQJ2GH.mjs';
17
18
  export { TEXT_FORMAT_PATTERNS, createTextValidator, resolveTextPattern } from './chunk-O73ROMWQ.mjs';
18
- import { SchemaError, SchemaErrorCode, ValidationError, DuplicateError, NotFoundError } from './chunk-HOVUEYEQ.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-HOVUEYEQ.mjs';
19
+ import { ValidationError, SchemaError, SchemaErrorCode, DuplicateError, NotFoundError } from './chunk-RUO25ERR.mjs';
20
+ 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-RUO25ERR.mjs';
20
21
  import './chunk-AYVHMVKQ.mjs';
21
22
  import './chunk-YUFTHPOE.mjs';
22
23
  import { formatPhoneForDisplay, normalizeCountrylessPhoneNumber, normalizePhoneNumber } from './chunk-R5LAJCBU.mjs';
23
- import './chunk-GO6LQADH.mjs';
24
24
  export { DEFAULT_VALIDATION_MESSAGES, formatZodErrors } from './chunk-HRQEZUAA.mjs';
25
25
  import { ICONS, SKILL_NAME_MAX_LENGTH, SKILL_DESCRIPTION_MAX_LENGTH, MEMORY_NAME_MAX_LENGTH, MEMORY_DESCRIPTION_MAX_LENGTH, getCountryDisplayNameByIso3 } from '@stndrds/constants';
26
26
  import z2, { z } from 'zod';
@@ -69,6 +69,24 @@ var BEHAVIOR_PROPERTIES = [
69
69
  var PRESENTATION_PROPERTIES = ["label", "description", "placeholder", "icon"];
70
70
 
71
71
  // src/types/attributes.ts
72
+ var ATTRIBUTE_TYPES = [
73
+ "text",
74
+ "richtext",
75
+ "number",
76
+ "checkbox",
77
+ "date",
78
+ "phone",
79
+ "currency",
80
+ "status",
81
+ "location",
82
+ "select",
83
+ "multiselect",
84
+ "user",
85
+ "relation",
86
+ "formula",
87
+ "rollup",
88
+ "document"
89
+ ];
72
90
  var RELATION_TARGET_ANY = "*";
73
91
  function isUniversalRelation(attr) {
74
92
  return attr.targets.length === 1 && attr.targets[0].object === RELATION_TARGET_ANY;
@@ -217,6 +235,13 @@ function isOpenToolPartState(state) {
217
235
  function isToolApprovalState(state) {
218
236
  return TOOL_APPROVAL_STATES.includes(state);
219
237
  }
238
+ function compareAgentSessionMessages(left, right) {
239
+ const createdAtOrder = left.createdAt.getTime() - right.createdAt.getTime();
240
+ return createdAtOrder === 0 ? left.id.localeCompare(right.id) : createdAtOrder;
241
+ }
242
+ function orderAgentSessionMessages(messages) {
243
+ return [...messages].sort(compareAgentSessionMessages);
244
+ }
220
245
  var TODO_STATUSES = ["pending", "in_progress", "completed", "blocked"];
221
246
  var MAX_TODOS = 50;
222
247
  var MAX_TODO_ID_CHARS = 80;
@@ -1134,6 +1159,12 @@ function assertUniqueBy(items, getKey, buildError) {
1134
1159
  seen.add(key);
1135
1160
  }
1136
1161
  }
1162
+ var ATTRIBUTE_NAME_SCHEMA = z2.string().min(1, "Attribute name cannot be empty").max(MAX_NAME_LENGTH, `Attribute name is too long (max ${MAX_NAME_LENGTH} characters)`).regex(ATTRIBUTE_NAME_REGEX, {
1163
+ message: "Invalid attribute name format.\nName must be a valid variable identifier:\n \u2705 Valid: 'firstName', 'first_name', 'FirstName', 'FIRST_NAME'\n \u274C Invalid: 'first-name', 'first name', '123name', 'first.name'"
1164
+ }).refine(
1165
+ (name) => !RESERVED_ATTRIBUTE_NAMES.includes(name),
1166
+ { message: "This is a reserved attribute name" }
1167
+ );
1137
1168
  function validateAttributeName(name) {
1138
1169
  if (!name || name.length === 0) {
1139
1170
  throw new Error("[AttributeBuilder] Attribute name cannot be empty");
@@ -5256,6 +5287,8 @@ function liveChannelKey(channel) {
5256
5287
  return `user:${encodeURIComponent(channel.actorId)}`;
5257
5288
  case "conversation":
5258
5289
  return `conversation:${encodeURIComponent(channel.sessionId)}`;
5290
+ case "architect-draft":
5291
+ return `architect-draft:${encodeURIComponent(channel.actorId)}`;
5259
5292
  }
5260
5293
  }
5261
5294
  function decodeLiveChannelPart(part) {
@@ -5297,6 +5330,10 @@ function parseLiveChannelKey(key) {
5297
5330
  const actorId = decodeLiveChannelPart(parts[1]);
5298
5331
  return actorId ? { kind: "user", actorId } : null;
5299
5332
  }
5333
+ if (parts[0] === "architect-draft" && parts.length === 2 && parts[1]) {
5334
+ const actorId = decodeLiveChannelPart(parts[1]);
5335
+ return actorId ? { kind: "architect-draft", actorId } : null;
5336
+ }
5300
5337
  if (parts[0] === "conversation" && parts.length === 2 && parts[1]) {
5301
5338
  const sessionId = decodeLiveChannelPart(parts[1]);
5302
5339
  return sessionId ? { kind: "conversation", sessionId } : null;
@@ -5317,11 +5354,13 @@ var LIVE_EVENT_TYPE_REGISTRY = {
5317
5354
  "notification.created": true,
5318
5355
  "notification.recipient.patch": true,
5319
5356
  "notification.count.patch": true,
5357
+ "notification.inbox.archived": true,
5320
5358
  "conversation.renamed": true,
5321
5359
  "browser.preview.updated": true,
5322
5360
  "reflex.state.changed": true,
5323
5361
  "reflex.run.completed": true,
5324
5362
  "reflex.authoring.progress": true,
5363
+ "architect.draft.updated": true,
5325
5364
  "channel.revoked": true
5326
5365
  };
5327
5366
  var LIVE_EVENT_TYPES = Object.keys(LIVE_EVENT_TYPE_REGISTRY);
@@ -5387,6 +5426,13 @@ var RECORD_LIVE_SNAPSHOT_KEYS = [
5387
5426
  "lastUpdatedBy",
5388
5427
  "schemaVersion"
5389
5428
  ];
5429
+ var NOTIFICATION_INBOX_ARCHIVED_PAYLOAD_KEYS = [
5430
+ "type",
5431
+ "targetActorId",
5432
+ "archivedCount",
5433
+ "version",
5434
+ "updatedAt"
5435
+ ];
5390
5436
  function isLiveEventType(value) {
5391
5437
  return typeof value === "string" && LIVE_EVENT_TYPES.includes(value);
5392
5438
  }
@@ -5421,6 +5467,8 @@ function isLiveEventPayloadForType(type, payload) {
5421
5467
  return isNotificationRecipientPatchPayload(payload);
5422
5468
  case "notification.count.patch":
5423
5469
  return isNotificationCountPatchPayload(payload);
5470
+ case "notification.inbox.archived":
5471
+ return isNotificationInboxArchivedPayload(payload);
5424
5472
  case "conversation.renamed":
5425
5473
  return isConversationRenamedPayload(payload);
5426
5474
  case "browser.preview.updated":
@@ -5431,6 +5479,8 @@ function isLiveEventPayloadForType(type, payload) {
5431
5479
  return isReflexRunCompletedPayload(payload);
5432
5480
  case "reflex.authoring.progress":
5433
5481
  return isReflexAuthoringProgressPayload(payload);
5482
+ case "architect.draft.updated":
5483
+ return isArchitectDraftUpdatedPayload(payload);
5434
5484
  case "channel.revoked":
5435
5485
  return isChannelRevokedPayload(payload);
5436
5486
  default:
@@ -5556,6 +5606,9 @@ function isNotificationRecipientPatchPayload(payload) {
5556
5606
  function isNotificationCountPatchPayload(payload) {
5557
5607
  return payload.type === "notification.count.patch" && hasString(payload, "targetActorId") && hasVersion(payload, "unread") && hasVersion(payload, "pendingWork") && hasVersion(payload, "version") && hasIsoDateString(payload, "updatedAt");
5558
5608
  }
5609
+ function isNotificationInboxArchivedPayload(payload) {
5610
+ return payload.type === "notification.inbox.archived" && hasOnlyKeys(payload, NOTIFICATION_INBOX_ARCHIVED_PAYLOAD_KEYS) && hasNonEmptyString(payload, "targetActorId") && hasVersion(payload, "archivedCount") && hasVersion(payload, "version") && hasIsoDateString(payload, "updatedAt");
5611
+ }
5559
5612
  function isConversationRenamedPayload(payload) {
5560
5613
  return payload.type === "conversation.renamed" && hasString(payload, "sessionId") && hasString(payload, "title") && hasVersion(payload, "version") && hasString(payload, "updatedAt");
5561
5614
  }
@@ -5575,6 +5628,20 @@ var REFLEX_SERVED_MODES = [
5575
5628
  "promoted",
5576
5629
  "lkg"
5577
5630
  ];
5631
+ var ARCHITECT_DRAFT_STATUSES = [
5632
+ "composing",
5633
+ "published",
5634
+ "discarded"
5635
+ ];
5636
+ function isArchitectDraftUpdatedPayload(payload) {
5637
+ if (payload.type !== "architect.draft.updated" || !isRecord2(payload.draft)) {
5638
+ return false;
5639
+ }
5640
+ const draft = payload.draft;
5641
+ return hasNonEmptyString(draft, "id") && hasNonEmptyString(draft, "actorId") && isNullableString(draft.agentSessionId) && // Each operation was parsed by the registry before it was persisted; the
5642
+ // wire check stops at the shape realtime itself is responsible for.
5643
+ Array.isArray(draft.operations) && draft.operations.every(isRecord2) && isRecord2(draft.baselines) && isOneOf(draft.status, ARCHITECT_DRAFT_STATUSES);
5644
+ }
5578
5645
  function isReflexStateChangedPayload(payload) {
5579
5646
  return payload.type === "reflex.state.changed" && hasNonEmptyString(payload, "reflexId") && isOneOf(payload.state, REFLEX_STATES) && hasIsoDateString(payload, "updatedAt");
5580
5647
  }
@@ -7589,11 +7656,243 @@ var persistedSchemaPlanSchema = z.preprocess(
7589
7656
  boundSerializedPlanInput,
7590
7657
  structuralPersistedSchemaPlanSchema
7591
7658
  );
7659
+ var nonNegativeNumberSchema = z.number().finite().nonnegative();
7660
+ var toolImpactSchema = z.object({
7661
+ label: z.string(),
7662
+ denied: z.boolean().optional(),
7663
+ deletion: z.object({
7664
+ target: z.string().optional(),
7665
+ count: nonNegativeNumberSchema.optional(),
7666
+ restorableDays: nonNegativeNumberSchema.optional()
7667
+ }).strict().optional(),
7668
+ counts: z.record(z.string(), nonNegativeNumberSchema).optional(),
7669
+ warnings: z.array(z.string()).optional()
7670
+ }).strict();
7671
+ var agentMessagePartSchema = z.union([
7672
+ z.object({ type: z.literal("text"), text: z.string() }).strict(),
7673
+ z.object({ type: z.literal("reasoning"), text: z.string() }).strict(),
7674
+ z.object({ type: z.literal("error"), error: z.string(), errorClass: z.string().optional() }).strict(),
7675
+ z.object({
7676
+ type: z.literal("tool"),
7677
+ toolCallId: z.string(),
7678
+ name: z.string(),
7679
+ args: z.record(z.string(), z.unknown()),
7680
+ result: z.unknown().optional(),
7681
+ error: z.string().optional(),
7682
+ errorCode: z.enum(["output_limit_reached", "interrupted"]).optional(),
7683
+ state: z.enum([
7684
+ "streaming",
7685
+ "running",
7686
+ "completed",
7687
+ "error",
7688
+ "approval-requested",
7689
+ "approval-responded",
7690
+ "approval-dispatched"
7691
+ ]),
7692
+ durationMs: nonNegativeNumberSchema.optional(),
7693
+ approvalId: z.string().optional(),
7694
+ approvalImpact: toolImpactSchema.optional(),
7695
+ approved: z.boolean().optional(),
7696
+ approvalReason: z.string().optional(),
7697
+ approvalRelaxableByAuto: z.boolean().optional()
7698
+ }).strict(),
7699
+ z.object({
7700
+ type: z.literal("file"),
7701
+ fileId: z.string(),
7702
+ name: z.string(),
7703
+ mimeType: z.string()
7704
+ }).strict(),
7705
+ z.object({
7706
+ type: z.literal("compaction"),
7707
+ state: z.literal("in-progress"),
7708
+ reason: z.enum(["preflight_threshold", "overflow_recovery"]),
7709
+ estimatedTokens: nonNegativeNumberSchema.optional(),
7710
+ reportedTokens: nonNegativeNumberSchema.optional()
7711
+ }).strict(),
7712
+ z.object({
7713
+ type: z.literal("compaction"),
7714
+ state: z.literal("completed"),
7715
+ tokensBefore: nonNegativeNumberSchema,
7716
+ tokensAfter: nonNegativeNumberSchema,
7717
+ tokensSaved: nonNegativeNumberSchema,
7718
+ strategy: z.enum(["no-op", "summary", "truncation"]),
7719
+ durationMs: nonNegativeNumberSchema,
7720
+ summary: z.string().optional()
7721
+ }).strict(),
7722
+ z.object({
7723
+ type: z.literal("compaction"),
7724
+ state: z.literal("failed"),
7725
+ reason: z.string(),
7726
+ durationMs: nonNegativeNumberSchema.optional()
7727
+ }).strict()
7728
+ ]);
7729
+ var agentMessageAttachmentSchema = z.object({
7730
+ id: z.string(),
7731
+ name: z.string(),
7732
+ mimeType: z.string(),
7733
+ size: nonNegativeNumberSchema
7734
+ }).strict();
7735
+ var mentionReferenceSchema = z.object({
7736
+ id: z.string(),
7737
+ // `MentionEntityType` is `"user" | "record" | (string & {})`, which accepts
7738
+ // exactly what `string` accepts but is not `Equal` to it, so a bare
7739
+ // `z.string()` fails this file's drift guard. The identity transform types
7740
+ // the output without touching validation: `z.string()` still runs first, so
7741
+ // a non-string is still rejected as `invalid_type` with the same message and
7742
+ // path — which matters, because `agentUIValidationError` copies the issue
7743
+ // code into the ValidationError it throws.
7744
+ type: z.string().transform((value) => value),
7745
+ entityId: z.string(),
7746
+ label: z.string(),
7747
+ objectName: z.string().optional(),
7748
+ startIndex: nonNegativeNumberSchema,
7749
+ endIndex: nonNegativeNumberSchema
7750
+ }).strict();
7751
+ var modelDefinitionSchema = z.object({
7752
+ provider: z.enum(["anthropic", "openai", "google", "mistral"]),
7753
+ model: z.string(),
7754
+ maxTokens: nonNegativeNumberSchema.optional(),
7755
+ contextWindow: nonNegativeNumberSchema.optional()
7756
+ }).strict();
7757
+ var durableDateSchema = z.union([
7758
+ z.date(),
7759
+ z.string().datetime({ offset: true }).transform((value) => new Date(value))
7760
+ ]);
7761
+ var agentSessionMessageSchema = z.object({
7762
+ id: z.string(),
7763
+ sessionId: z.string(),
7764
+ tenantId: z.string().optional(),
7765
+ runId: z.string().optional(),
7766
+ role: z.enum(["user", "assistant", "system", "tool"]),
7767
+ parts: z.array(agentMessagePartSchema),
7768
+ attachments: z.array(agentMessageAttachmentSchema).optional(),
7769
+ mentions: z.array(mentionReferenceSchema).optional(),
7770
+ model: modelDefinitionSchema.optional(),
7771
+ tokenUsage: z.object({ input: nonNegativeNumberSchema, output: nonNegativeNumberSchema }).strict().optional(),
7772
+ metadata: z.record(z.string(), z.unknown()).optional(),
7773
+ createdAt: durableDateSchema
7774
+ }).strict();
7775
+ var todoItemSchema = z.object({
7776
+ id: z.string(),
7777
+ description: z.string(),
7778
+ status: z.enum(["pending", "in_progress", "completed", "blocked"]),
7779
+ result: z.string().optional(),
7780
+ updatedAt: nonNegativeNumberSchema.optional()
7781
+ }).strict();
7782
+ var todoPlanSchema = z.object({
7783
+ id: z.string(),
7784
+ sessionId: z.string(),
7785
+ status: z.enum(["active", "completed", "abandoned"]),
7786
+ todos: z.array(todoItemSchema),
7787
+ version: nonNegativeNumberSchema,
7788
+ createdAt: z.string(),
7789
+ updatedAt: z.string(),
7790
+ completedAt: z.string().optional()
7791
+ }).strict();
7792
+ var customDataChunkSchemas = {
7793
+ "session-named": z.object({ name: z.string() }).strict(),
7794
+ "compaction-start": z.object({
7795
+ reason: z.enum(["preflight_threshold", "overflow_recovery"]),
7796
+ estimatedTokens: nonNegativeNumberSchema.optional(),
7797
+ reportedTokens: nonNegativeNumberSchema.optional()
7798
+ }).strict(),
7799
+ "compaction-end": z.object({
7800
+ tokensBefore: nonNegativeNumberSchema,
7801
+ tokensAfter: nonNegativeNumberSchema,
7802
+ tokensSaved: nonNegativeNumberSchema,
7803
+ strategy: z.enum(["no-op", "summary", "truncation"]),
7804
+ durationMs: nonNegativeNumberSchema,
7805
+ summary: z.string().optional()
7806
+ }).strict(),
7807
+ "compaction-failed": z.object({ reason: z.string() }).strict(),
7808
+ usage: z.object({
7809
+ inputTokens: nonNegativeNumberSchema,
7810
+ outputTokens: nonNegativeNumberSchema,
7811
+ totalTokens: nonNegativeNumberSchema,
7812
+ cacheReadTokens: nonNegativeNumberSchema.optional(),
7813
+ cacheCreationTokens: nonNegativeNumberSchema.optional(),
7814
+ contextWindow: nonNegativeNumberSchema,
7815
+ residentTokens: nonNegativeNumberSchema,
7816
+ utilization: z.number().finite().min(0).max(1),
7817
+ costUsd: nonNegativeNumberSchema.optional()
7818
+ }).strict(),
7819
+ "message-persisted": z.object({ message: agentSessionMessageSchema }).strict(),
7820
+ "message-updated": z.object({ message: agentSessionMessageSchema }).strict(),
7821
+ "todo-plan-update": z.object({ plan: todoPlanSchema }).strict(),
7822
+ "approval-context": z.object({
7823
+ approvalId: z.string(),
7824
+ toolCallId: z.string(),
7825
+ impact: toolImpactSchema.optional(),
7826
+ relaxableByAuto: z.boolean().optional()
7827
+ }).strict()
7828
+ };
7829
+ function isAgentUIDataName(value) {
7830
+ return value in customDataChunkSchemas;
7831
+ }
7832
+ function agentUIValidationError(issues) {
7833
+ return new ValidationError(
7834
+ "Invalid agent UI message chunk",
7835
+ issues.map((issue) => ({
7836
+ path: issue.path.map(String),
7837
+ message: issue.message,
7838
+ code: issue.code
7839
+ }))
7840
+ );
7841
+ }
7842
+ function assertCustomAgentUIMessageChunk(value) {
7843
+ if (typeof value !== "object" || value === null || typeof value.type !== "string") {
7844
+ throw new ValidationError("Invalid agent UI message chunk", [
7845
+ { path: ["type"], message: "Expected UI message chunk type", code: "invalid_type" }
7846
+ ]);
7847
+ }
7848
+ const type = value.type;
7849
+ if (!type.startsWith("data-")) {
7850
+ throw new ValidationError("Invalid agent UI message chunk", [
7851
+ { path: ["type"], message: "Expected agent data chunk type", code: "invalid_value" }
7852
+ ]);
7853
+ }
7854
+ const name = type.slice("data-".length);
7855
+ if (!isAgentUIDataName(name)) {
7856
+ throw new ValidationError("Invalid agent UI message chunk", [
7857
+ { path: ["type"], message: `Unknown agent UI data type: ${name}`, code: "invalid_value" }
7858
+ ]);
7859
+ }
7860
+ const chunkResult = z.object({
7861
+ type: z.literal(`data-${name}`),
7862
+ id: z.string().optional(),
7863
+ data: customDataChunkSchemas[name],
7864
+ transient: z.boolean().optional()
7865
+ }).strict().safeParse(value);
7866
+ if (!chunkResult.success) throw agentUIValidationError(chunkResult.error.issues);
7867
+ return chunkResult.data;
7868
+ }
7869
+ function agentDataChunk(name, data, options) {
7870
+ return assertCustomAgentUIMessageChunk({
7871
+ type: `data-${name}`,
7872
+ ...options?.id !== void 0 ? { id: options.id } : {},
7873
+ data,
7874
+ ...options?.transient !== void 0 ? { transient: options.transient } : {}
7875
+ });
7876
+ }
7592
7877
 
7593
7878
  // src/architect/define-operation.ts
7594
7879
  function defineOperation(def) {
7595
7880
  return def;
7596
7881
  }
7882
+ function definePresentation(focus, impact, propertyPath) {
7883
+ const navigation = impact === "atomic" ? "none" : impact === "local" ? "if-not-visible" : "follow";
7884
+ return (op) => {
7885
+ const path = propertyPath?.(op);
7886
+ return {
7887
+ impact,
7888
+ navigation,
7889
+ focus: {
7890
+ ...focus(op),
7891
+ ...path === void 0 ? {} : { propertyPath: path }
7892
+ }
7893
+ };
7894
+ };
7895
+ }
7597
7896
  var operationBase = { id: z.string().min(1) };
7598
7897
  var viewOperationBase = { ...operationBase, viewId: z.string().min(1) };
7599
7898
  function mapView(state, viewId, fn) {
@@ -7643,18 +7942,47 @@ function locateField(tab, fieldId) {
7643
7942
  }
7644
7943
  throw new ValidationError(`Field slot "${fieldId}" is not in tab "${tab.id}"`, []);
7645
7944
  }
7646
- var tabPayload = z.custom(
7647
- (value) => typeof value === "object" && value !== null && "id" in value && "type" in value,
7648
- { message: "A tab must be an object carrying id and type" }
7649
- );
7650
- var groupPayload = z.custom(
7651
- (value) => typeof value === "object" && value !== null && "id" in value && "fields" in value,
7652
- { message: "A group must be an object carrying id and fields" }
7653
- );
7654
- var fieldPayload = z.custom(
7655
- (value) => typeof value === "object" && value !== null && "id" in value,
7656
- { message: "A field slot must be an object carrying an id" }
7657
- );
7945
+ function viewFocus(op) {
7946
+ return { viewId: op.viewId };
7947
+ }
7948
+ function tabFocus(op) {
7949
+ return { viewId: op.viewId, tabId: op.tabId };
7950
+ }
7951
+ function groupFocus(op) {
7952
+ return { viewId: op.viewId, tabId: op.tabId, groupId: op.groupId };
7953
+ }
7954
+ function fieldFocus(op) {
7955
+ return { viewId: op.viewId, tabId: op.tabId, fieldId: op.fieldId };
7956
+ }
7957
+ function addTabFocus(op) {
7958
+ return { viewId: op.viewId, tabId: op.tab.id };
7959
+ }
7960
+ function addGroupFocus(op) {
7961
+ return { viewId: op.viewId, tabId: op.tabId, groupId: op.group.id };
7962
+ }
7963
+ function addFieldFocus(op) {
7964
+ return {
7965
+ viewId: op.viewId,
7966
+ tabId: op.tabId,
7967
+ groupId: op.groupId,
7968
+ fieldId: op.field.id
7969
+ };
7970
+ }
7971
+ function moveFieldFocus(op) {
7972
+ return {
7973
+ viewId: op.viewId,
7974
+ tabId: op.tabId,
7975
+ groupId: op.toGroupId,
7976
+ fieldId: op.fieldId
7977
+ };
7978
+ }
7979
+ function firstChangedProperty(op) {
7980
+ const keys = Object.keys(op.changes).sort();
7981
+ return keys.length === 1 ? [keys[0]] : void 0;
7982
+ }
7983
+ var tabPayload = detailTabDraftSchema;
7984
+ var groupPayload = groupWriteSchema;
7985
+ var fieldPayload = fieldSlotSchema;
7658
7986
  var addTabSchema = z.object({
7659
7987
  ...viewOperationBase,
7660
7988
  type: z.literal("add_tab"),
@@ -7669,7 +7997,8 @@ var addTab = defineOperation({
7669
7997
  }
7670
7998
  return { ...view, tabs: [...view.tabs, op.tab] };
7671
7999
  }),
7672
- focus: (op) => ({ viewId: op.viewId, tabId: op.tab.id }),
8000
+ focus: addTabFocus,
8001
+ presentation: definePresentation(addTabFocus, "local"),
7673
8002
  describe: (op) => `Ajoute l'onglet \xAB ${op.tab.label} \xBB`
7674
8003
  });
7675
8004
  var removeTabSchema = z.object({
@@ -7686,18 +8015,30 @@ var removeTab = defineOperation({
7686
8015
  }
7687
8016
  return { ...view, tabs: view.tabs.filter((t) => t.id !== op.tabId) };
7688
8017
  }),
7689
- focus: (op) => ({ viewId: op.viewId }),
8018
+ focus: tabFocus,
8019
+ presentation: definePresentation(tabFocus, "local"),
7690
8020
  describe: (op) => `Supprime l'onglet ${op.tabId}`
7691
8021
  });
8022
+ var updateTabChanges = z.object({
8023
+ label: z.string().min(1).optional(),
8024
+ icon: iconNameSchema.optional(),
8025
+ order: z.number().int().optional()
8026
+ });
8027
+ var UPDATE_TAB_CHANGE_KEYS = Object.keys(
8028
+ updateTabChanges.shape
8029
+ );
7692
8030
  var updateTabSchema = z.object({
7693
8031
  ...viewOperationBase,
7694
8032
  type: z.literal("update_tab"),
7695
8033
  tabId: z.string().min(1),
7696
- changes: z.object({
7697
- label: z.string().min(1).optional(),
7698
- icon: z.custom((v) => typeof v === "string" && v.length > 0).optional(),
7699
- order: z.number().int().optional()
7700
- }).refine((c) => Object.keys(c).length > 0, "update_tab needs at least one change")
8034
+ changes: updateTabChanges.refine(
8035
+ (c) => Object.keys(c).length > 0,
8036
+ "update_tab needs at least one change"
8037
+ )
8038
+ });
8039
+ var updateTabFocus = (op) => ({
8040
+ viewId: op.viewId,
8041
+ tabId: op.tabId
7701
8042
  });
7702
8043
  var updateTab = defineOperation({
7703
8044
  type: "update_tab",
@@ -7711,7 +8052,8 @@ var updateTab = defineOperation({
7711
8052
  tabs: view.tabs.map((t) => t.id === op.tabId ? { ...t, ...op.changes } : t)
7712
8053
  };
7713
8054
  }),
7714
- focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
8055
+ focus: updateTabFocus,
8056
+ presentation: definePresentation(updateTabFocus, "atomic", firstChangedProperty),
7715
8057
  describe: (op) => op.changes.label ? `Renomme l'onglet en \xAB ${op.changes.label} \xBB` : `Modifie l'onglet ${op.tabId}`
7716
8058
  });
7717
8059
  var reorderTabsSchema = z.object({
@@ -7726,7 +8068,8 @@ var reorderTabs = defineOperation({
7726
8068
  ...view,
7727
8069
  tabs: reorderById(view.tabs, op.tabOrder, "Tab")
7728
8070
  })),
7729
- focus: (op) => ({ viewId: op.viewId }),
8071
+ focus: viewFocus,
8072
+ presentation: definePresentation(viewFocus, "local"),
7730
8073
  describe: () => "R\xE9ordonne les onglets"
7731
8074
  });
7732
8075
  var addGroupSchema = z.object({
@@ -7751,7 +8094,8 @@ var addGroup = defineOperation({
7751
8094
  return { ...tab, groups: [...tab.groups, op.group] };
7752
8095
  })
7753
8096
  ),
7754
- focus: (op) => ({ viewId: op.viewId, tabId: op.tabId, groupId: op.group.id }),
8097
+ focus: addGroupFocus,
8098
+ presentation: definePresentation(addGroupFocus, "local"),
7755
8099
  describe: (op) => `Ajoute le groupe \xAB ${op.group.label} \xBB`
7756
8100
  });
7757
8101
  var removeGroupSchema = z.object({
@@ -7771,7 +8115,8 @@ var removeGroup = defineOperation({
7771
8115
  return { ...tab, groups: tab.groups.filter((g) => g.id !== op.groupId) };
7772
8116
  })
7773
8117
  ),
7774
- focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
8118
+ focus: groupFocus,
8119
+ presentation: definePresentation(groupFocus, "local"),
7775
8120
  describe: (op) => `Supprime le groupe ${op.groupId}`
7776
8121
  });
7777
8122
  var updateGroupSchema = z.object({
@@ -7787,6 +8132,11 @@ var updateGroupSchema = z.object({
7787
8132
  order: z.number().int().optional()
7788
8133
  }).refine((c) => Object.keys(c).length > 0, "update_group needs at least one change")
7789
8134
  });
8135
+ var updateGroupFocus = (op) => ({
8136
+ viewId: op.viewId,
8137
+ tabId: op.tabId,
8138
+ groupId: op.groupId
8139
+ });
7790
8140
  var updateGroup = defineOperation({
7791
8141
  type: "update_group",
7792
8142
  schema: updateGroupSchema,
@@ -7801,7 +8151,8 @@ var updateGroup = defineOperation({
7801
8151
  };
7802
8152
  })
7803
8153
  ),
7804
- focus: (op) => ({ viewId: op.viewId, tabId: op.tabId, groupId: op.groupId }),
8154
+ focus: updateGroupFocus,
8155
+ presentation: definePresentation(updateGroupFocus, "atomic", firstChangedProperty),
7805
8156
  describe: (op) => op.changes.label ? `Renomme le groupe en \xAB ${op.changes.label} \xBB` : "Modifie le groupe"
7806
8157
  });
7807
8158
  var reorderGroupsSchema = z.object({
@@ -7821,7 +8172,8 @@ var reorderGroups = defineOperation({
7821
8172
  groups: reorderById(tab.groups, op.groupOrder, "Group")
7822
8173
  }))
7823
8174
  ),
7824
- focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
8175
+ focus: tabFocus,
8176
+ presentation: definePresentation(tabFocus, "local"),
7825
8177
  describe: () => "R\xE9ordonne les groupes"
7826
8178
  });
7827
8179
  var addFieldSchema = z.object({
@@ -7859,12 +8211,8 @@ var addField = defineOperation({
7859
8211
  };
7860
8212
  })
7861
8213
  ),
7862
- focus: (op) => ({
7863
- viewId: op.viewId,
7864
- tabId: op.tabId,
7865
- groupId: op.groupId,
7866
- fieldId: op.field.id
7867
- }),
8214
+ focus: addFieldFocus,
8215
+ presentation: definePresentation(addFieldFocus, "local"),
7868
8216
  describe: (op) => `Ajoute le champ ${op.field.attribute ?? op.field.id}`
7869
8217
  });
7870
8218
  var removeFieldSchema = z.object({
@@ -7889,7 +8237,8 @@ var removeField = defineOperation({
7889
8237
  };
7890
8238
  })
7891
8239
  ),
7892
- focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
8240
+ focus: fieldFocus,
8241
+ presentation: definePresentation(fieldFocus, "local"),
7893
8242
  describe: (op) => `Retire le champ ${op.fieldId}`
7894
8243
  });
7895
8244
  var moveFieldSchema = z.object({
@@ -7939,12 +8288,8 @@ var moveField = defineOperation({
7939
8288
  };
7940
8289
  })
7941
8290
  ),
7942
- focus: (op) => ({
7943
- viewId: op.viewId,
7944
- tabId: op.tabId,
7945
- groupId: op.toGroupId,
7946
- fieldId: op.fieldId
7947
- }),
8291
+ focus: moveFieldFocus,
8292
+ presentation: definePresentation(moveFieldFocus, "local"),
7948
8293
  describe: (op) => `D\xE9place le champ ${op.fieldId} vers le groupe ${op.toGroupId}`
7949
8294
  });
7950
8295
  var updateFieldSchema = z.object({
@@ -7958,6 +8303,11 @@ var updateFieldSchema = z.object({
7958
8303
  span: z.number().int().min(1).max(12).optional()
7959
8304
  }).refine((c) => Object.keys(c).length > 0, "update_field needs at least one change")
7960
8305
  });
8306
+ var updateFieldFocus = (op) => ({
8307
+ viewId: op.viewId,
8308
+ tabId: op.tabId,
8309
+ fieldId: op.fieldId
8310
+ });
7961
8311
  var updateField = defineOperation({
7962
8312
  type: "update_field",
7963
8313
  schema: updateFieldSchema,
@@ -7977,22 +8327,111 @@ var updateField = defineOperation({
7977
8327
  };
7978
8328
  })
7979
8329
  ),
7980
- focus: (op) => ({ viewId: op.viewId, tabId: op.tabId, fieldId: op.fieldId }),
8330
+ focus: updateFieldFocus,
8331
+ presentation: definePresentation(updateFieldFocus, "atomic", firstChangedProperty),
7981
8332
  describe: (op) => `Modifie le champ ${op.fieldId}`
7982
8333
  });
8334
+ var updateTableTabChanges = z.object({
8335
+ /**
8336
+ * Where the table reads its rows from — a `TableSource`, not a name: a
8337
+ * direct relation, or the inverse of one. Kept with `columns` on purpose:
8338
+ * the source picker posts `{ source, columns: [] }` as one gesture, and
8339
+ * splitting the pair across two operations would wipe the column list while
8340
+ * the source change vanished (#2763, #2787).
8341
+ */
8342
+ source: tableSourceSchema.optional(),
8343
+ columns: columnsSchema.optional(),
8344
+ // Nullable, not merely optional: the panels clear a filter list or a sort
8345
+ // list by sending `null`, because `undefined` does not survive
8346
+ // `JSON.stringify` and the operation would arrive with no changes at all
8347
+ // (#2787). `apply` drops the key rather than storing the null.
8348
+ filters: filterStateSchema.nullable().optional(),
8349
+ sorts: sortsSchema.nullable().optional(),
8350
+ allowCreate: z.boolean().optional(),
8351
+ allowEdit: z.boolean().optional(),
8352
+ allowDelete: z.boolean().optional(),
8353
+ createMode: z.enum(["redirect", "inline", "peek"]).optional()
8354
+ });
8355
+ var UPDATE_TABLE_TAB_CHANGE_KEYS = Object.keys(
8356
+ updateTableTabChanges.shape
8357
+ );
8358
+ var updateTabConfigChanges = z.object({
8359
+ /** Address attributes an emails/meetings tab reads. */
8360
+ emailAttributeIds: z.array(z.string().min(1)).optional(),
8361
+ /**
8362
+ * The attribute a richtext tab edits, and the one it titles itself with.
8363
+ * `titleAttribute` is nullable because "None" is a real choice — and null,
8364
+ * not undefined, because `JSON.stringify` drops undefined-valued keys and
8365
+ * the operation would arrive with no changes at all.
8366
+ */
8367
+ attribute: z.string().min(1).optional(),
8368
+ titleAttribute: z.string().min(1).nullable().optional(),
8369
+ /**
8370
+ * The component a custom tab renders, and the props handed to it. Both are
8371
+ * clearable for the same reason: the name is emptied on blur and the props
8372
+ * textarea is emptied to mean "none".
8373
+ */
8374
+ component: z.string().nullable().optional(),
8375
+ props: z.record(z.string(), z.unknown()).nullable().optional()
8376
+ });
8377
+ var UPDATE_TAB_CONFIG_CHANGE_KEYS = Object.keys(
8378
+ updateTabConfigChanges.shape
8379
+ );
8380
+ var TAB_CONFIG_FIELD_OWNERS = {
8381
+ emailAttributeIds: ["emails", "meetings"],
8382
+ attribute: ["richtext"],
8383
+ titleAttribute: ["richtext"],
8384
+ component: ["custom"],
8385
+ props: ["custom"]
8386
+ };
8387
+ var updateTabConfigSchema = z.object({
8388
+ ...viewOperationBase,
8389
+ type: z.literal("update_tab_config"),
8390
+ tabId: z.string().min(1),
8391
+ changes: updateTabConfigChanges.refine(
8392
+ (c) => Object.keys(c).length > 0,
8393
+ "update_tab_config needs at least one change"
8394
+ )
8395
+ });
8396
+ var updateTabConfigFocus = (op) => ({
8397
+ viewId: op.viewId,
8398
+ tabId: op.tabId
8399
+ });
8400
+ var updateTabConfig = defineOperation({
8401
+ type: "update_tab_config",
8402
+ schema: updateTabConfigSchema,
8403
+ apply: (state, op) => mapView(state, op.viewId, (view) => {
8404
+ const found = view.tabs.find((t) => t.id === op.tabId);
8405
+ if (!found) {
8406
+ throw new ValidationError(`Tab "${op.tabId}" is not in view "${view.id}"`, []);
8407
+ }
8408
+ for (const key of Object.keys(op.changes)) {
8409
+ const allowed = TAB_CONFIG_FIELD_OWNERS[key];
8410
+ if (allowed && !allowed.includes(found.type)) {
8411
+ throw new ValidationError(`"${key}" is not a setting of a "${found.type}" tab`, []);
8412
+ }
8413
+ }
8414
+ return {
8415
+ ...view,
8416
+ tabs: view.tabs.map((t) => t.id === op.tabId ? { ...t, ...op.changes } : t)
8417
+ };
8418
+ }),
8419
+ focus: updateTabConfigFocus,
8420
+ presentation: definePresentation(updateTabConfigFocus, "atomic", firstChangedProperty),
8421
+ describe: (op) => `Configure ${Object.keys(op.changes).join(", ")} sur l'onglet ${op.tabId}`
8422
+ });
7983
8423
  var updateTableTabSchema = z.object({
7984
8424
  ...viewOperationBase,
7985
8425
  type: z.literal("update_table_tab"),
7986
8426
  tabId: z.string().min(1),
7987
- changes: z.object({
7988
- columns: z.array(z.string().min(1)).optional(),
7989
- filters: z.custom().optional(),
7990
- sorts: z.custom().optional(),
7991
- allowCreate: z.boolean().optional(),
7992
- allowEdit: z.boolean().optional(),
7993
- allowDelete: z.boolean().optional(),
7994
- createMode: z.enum(["redirect", "inline", "peek"]).optional()
7995
- }).refine((c) => Object.keys(c).length > 0, "update_table_tab needs at least one change")
8427
+ changes: updateTableTabChanges.refine(
8428
+ (c) => Object.keys(c).length > 0,
8429
+ "update_table_tab needs at least one change"
8430
+ )
8431
+ });
8432
+ var updateTableTabFocus = (op) => ({
8433
+ viewId: op.viewId,
8434
+ tabId: op.tabId
7996
8435
  });
7997
8436
  var updateTableTab = defineOperation({
7998
8437
  type: "update_table_tab",
@@ -8003,12 +8442,20 @@ var updateTableTab = defineOperation({
8003
8442
  if (found.type !== "table") {
8004
8443
  throw new ValidationError(`Tab "${op.tabId}" is not a table tab`, []);
8005
8444
  }
8445
+ const entries = Object.entries(op.changes);
8446
+ const applied = Object.fromEntries(entries.filter(([, value]) => value !== null));
8447
+ const cleared = new Set(entries.filter(([, value]) => value === null).map(([key]) => key));
8006
8448
  return {
8007
8449
  ...view,
8008
- tabs: view.tabs.map((t) => t.id === op.tabId ? { ...t, ...op.changes } : t)
8450
+ tabs: view.tabs.map(
8451
+ (t) => t.id === op.tabId ? Object.fromEntries(
8452
+ Object.entries({ ...t, ...applied }).filter(([key]) => !cleared.has(key))
8453
+ ) : t
8454
+ )
8009
8455
  };
8010
8456
  }),
8011
- focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
8457
+ focus: updateTableTabFocus,
8458
+ presentation: definePresentation(updateTableTabFocus, "atomic", firstChangedProperty),
8012
8459
  describe: (op) => op.changes.columns ? `Affiche ${op.changes.columns.length} colonne(s) dans l'onglet ${op.tabId}` : `Modifie l'onglet ${op.tabId}`
8013
8460
  });
8014
8461
  var setSidePanelSchema = z.object({
@@ -8026,7 +8473,8 @@ var setSidePanel = defineOperation({
8026
8473
  sidePanel: op.sidePanel ?? void 0
8027
8474
  }
8028
8475
  })),
8029
- focus: (op) => ({ viewId: op.viewId }),
8476
+ focus: viewFocus,
8477
+ presentation: definePresentation(viewFocus, "atomic", () => ["config", "sidePanel"]),
8030
8478
  describe: (op) => op.sidePanel ? "Active le panneau lat\xE9ral" : "Retire le panneau lat\xE9ral"
8031
8479
  });
8032
8480
  var DETAIL_VIEW_OPERATIONS = [
@@ -8043,9 +8491,47 @@ var DETAIL_VIEW_OPERATIONS = [
8043
8491
  moveField,
8044
8492
  updateField,
8045
8493
  updateTableTab,
8494
+ updateTabConfig,
8046
8495
  setSidePanel
8047
8496
  ];
8048
8497
  var listTabBase = { ...viewOperationBase, tabId: z.string().min(1) };
8498
+ function viewFocus2(op) {
8499
+ return { viewId: op.viewId };
8500
+ }
8501
+ function tabFocus2(op) {
8502
+ return { viewId: op.viewId, tabId: op.tabId };
8503
+ }
8504
+ function addTabFocus2(op) {
8505
+ return { viewId: op.viewId, tabId: op.tab.id };
8506
+ }
8507
+ function firstChangedProperty2(op) {
8508
+ const keys = Object.keys(op.changes).sort();
8509
+ return keys.length === 1 ? [keys[0]] : void 0;
8510
+ }
8511
+ function withoutKanbanKeys(tab) {
8512
+ const rest = { ...tab };
8513
+ for (const key of LIST_TAB_KANBAN_KEYS) delete rest[key];
8514
+ return rest;
8515
+ }
8516
+ function withoutTableKeys(tab) {
8517
+ const rest = { ...tab };
8518
+ for (const key of LIST_TAB_TABLE_KEYS) delete rest[key];
8519
+ return rest;
8520
+ }
8521
+ function assertStillPublishableTab(before, after, viewId, tabId) {
8522
+ const parsed = listViewTabSchema.safeParse(after);
8523
+ if (!parsed.success) {
8524
+ if (!listViewTabSchema.safeParse(before).success) return after;
8525
+ const detail = parsed.error.issues.map(
8526
+ (issue) => issue.path.length ? `${issue.path.join(".")}: ${issue.message}` : issue.message
8527
+ ).join(", ");
8528
+ throw new ValidationError(
8529
+ `List tab "${tabId}" in view "${viewId}" would no longer be publishable: ${detail}`,
8530
+ []
8531
+ );
8532
+ }
8533
+ return after;
8534
+ }
8049
8535
  function mapListTab(state, viewId, tabId, fn) {
8050
8536
  return mapView(state, viewId, (view) => {
8051
8537
  const tabs = view.config.tabs ?? [];
@@ -8054,18 +8540,18 @@ function mapListTab(state, viewId, tabId, fn) {
8054
8540
  }
8055
8541
  return {
8056
8542
  ...view,
8057
- config: { ...view.config, tabs: tabs.map((t) => t.id === tabId ? fn(t) : t) }
8543
+ config: {
8544
+ ...view.config,
8545
+ tabs: tabs.map(
8546
+ (t) => t.id === tabId ? assertStillPublishableTab(t, fn(t), viewId, tabId) : t
8547
+ )
8548
+ }
8058
8549
  };
8059
8550
  });
8060
8551
  }
8061
- var listTabPayload = z.custom(
8062
- (value) => typeof value === "object" && value !== null && "id" in value,
8063
- { message: "A list tab must be an object carrying an id" }
8064
- );
8065
- var filterGroupPayload = z.custom(
8066
- (value) => value === null || typeof value === "object"
8067
- );
8068
- var sortRulesPayload = z.custom((value) => Array.isArray(value));
8552
+ var listTabPayload = listViewTabSchema;
8553
+ var filterGroupPayload = filterGroupSchema;
8554
+ var sortRulesPayload = sortsSchema;
8069
8555
  function setOnTab(type, key, valueSchema, describe) {
8070
8556
  const schema = z.object({ ...listTabBase, type: z.literal(type), value: valueSchema });
8071
8557
  return defineOperation({
@@ -8078,7 +8564,8 @@ function setOnTab(type, key, valueSchema, describe) {
8078
8564
  }
8079
8565
  return { ...tab, [key]: op.value };
8080
8566
  }),
8081
- focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
8567
+ focus: tabFocus2,
8568
+ presentation: definePresentation(tabFocus2, "atomic", () => [String(key)]),
8082
8569
  describe: (op) => describe(op.value)
8083
8570
  });
8084
8571
  }
@@ -8100,7 +8587,8 @@ var addListTab = defineOperation({
8100
8587
  }
8101
8588
  return { ...view, config: { ...view.config, tabs: [...tabs, op.tab] } };
8102
8589
  }),
8103
- focus: (op) => ({ viewId: op.viewId, tabId: op.tab.id }),
8590
+ focus: addTabFocus2,
8591
+ presentation: definePresentation(addTabFocus2, "local"),
8104
8592
  describe: (op) => `Ajoute l'onglet \xAB ${op.tab.label} \xBB`
8105
8593
  });
8106
8594
  var removeListTabSchema = z.object({
@@ -8120,7 +8608,8 @@ var removeListTab = defineOperation({
8120
8608
  config: { ...view.config, tabs: tabs.filter((t) => t.id !== op.tabId) }
8121
8609
  };
8122
8610
  }),
8123
- focus: (op) => ({ viewId: op.viewId }),
8611
+ focus: tabFocus2,
8612
+ presentation: definePresentation(tabFocus2, "local"),
8124
8613
  describe: (op) => `Supprime l'onglet ${op.tabId}`
8125
8614
  });
8126
8615
  var updateListTabSchema = z.object({
@@ -8128,16 +8617,21 @@ var updateListTabSchema = z.object({
8128
8617
  type: z.literal("update_list_tab"),
8129
8618
  changes: z.object({
8130
8619
  label: z.string().min(1).optional(),
8131
- icon: z.custom((v) => typeof v === "string" && v.length > 0).optional(),
8620
+ icon: iconNameSchema.optional(),
8132
8621
  default: z.boolean().optional(),
8133
8622
  visibility: z.enum(LIST_VIEW_TAB_VISIBILITIES).optional()
8134
8623
  }).refine((c) => Object.keys(c).length > 0, "update_list_tab needs at least one change")
8135
8624
  });
8625
+ var updateListTabFocus = (op) => ({
8626
+ viewId: op.viewId,
8627
+ tabId: op.tabId
8628
+ });
8136
8629
  var updateListTab = defineOperation({
8137
8630
  type: "update_list_tab",
8138
8631
  schema: updateListTabSchema,
8139
8632
  apply: (state, op) => mapListTab(state, op.viewId, op.tabId, (tab) => ({ ...tab, ...op.changes })),
8140
- focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
8633
+ focus: updateListTabFocus,
8634
+ presentation: definePresentation(updateListTabFocus, "atomic", firstChangedProperty2),
8141
8635
  describe: (op) => op.changes.label ? `Renomme l'onglet en \xAB ${op.changes.label} \xBB` : `Modifie l'onglet ${op.tabId}`
8142
8636
  });
8143
8637
  var reorderListTabsSchema = z.object({
@@ -8155,7 +8649,8 @@ var reorderListTabs = defineOperation({
8155
8649
  tabs: reorderById(view.config.tabs ?? [], op.tabOrder, "List tab")
8156
8650
  }
8157
8651
  })),
8158
- focus: (op) => ({ viewId: op.viewId }),
8652
+ focus: viewFocus2,
8653
+ presentation: definePresentation(viewFocus2, "local"),
8159
8654
  describe: () => "R\xE9ordonne les onglets"
8160
8655
  });
8161
8656
  var setColumns = setOnTab(
@@ -8172,18 +8667,47 @@ var setColumnSizing = setOnTab(
8172
8667
  z.record(z.string(), z.number().int().positive()),
8173
8668
  () => "Ajuste la largeur des colonnes"
8174
8669
  );
8175
- var setLayout = setOnTab(
8176
- "set_layout",
8177
- "layout",
8178
- z.enum(["table", "kanban"]),
8179
- (value) => `Passe en affichage ${value}`
8180
- );
8181
- var setGroupBy = setOnTab(
8182
- "set_group_by",
8183
- "groupByAttribute",
8184
- z.string().min(1).nullable(),
8185
- (value) => value ? `Regroupe par ${value}` : "Retire le regroupement"
8186
- );
8670
+ var setLayoutSchema = z.object({
8671
+ ...listTabBase,
8672
+ type: z.literal("set_layout"),
8673
+ value: z.enum(["table", "kanban"])
8674
+ });
8675
+ var setLayout = defineOperation({
8676
+ type: "set_layout",
8677
+ schema: setLayoutSchema,
8678
+ apply: (state, op) => mapListTab(state, op.viewId, op.tabId, (tab) => {
8679
+ if (op.value === "table") return { ...withoutKanbanKeys(tab), layout: "table" };
8680
+ if (tab.groupByAttribute === void 0) {
8681
+ throw new ValidationError(
8682
+ `List tab "${op.tabId}" cannot switch to kanban without a group attribute \u2014 use set_group_by, which switches the layout itself`,
8683
+ []
8684
+ );
8685
+ }
8686
+ return { ...withoutTableKeys(tab), layout: "kanban" };
8687
+ }),
8688
+ focus: tabFocus2,
8689
+ presentation: definePresentation(tabFocus2, "atomic", () => ["layout"]),
8690
+ describe: (op) => `Passe en affichage ${op.value}`
8691
+ });
8692
+ var setGroupBySchema = z.object({
8693
+ ...listTabBase,
8694
+ type: z.literal("set_group_by"),
8695
+ value: z.string().min(1).nullable()
8696
+ });
8697
+ var setGroupBy = defineOperation({
8698
+ type: "set_group_by",
8699
+ schema: setGroupBySchema,
8700
+ apply: (state, op) => mapListTab(
8701
+ state,
8702
+ op.viewId,
8703
+ op.tabId,
8704
+ (tab) => op.value === null ? { ...withoutKanbanKeys(tab), layout: "table" } : { ...withoutTableKeys(tab), layout: "kanban", groupByAttribute: op.value }
8705
+ ),
8706
+ focus: tabFocus2,
8707
+ // The layout flip is a side effect; the addressable property stays the group.
8708
+ presentation: definePresentation(tabFocus2, "atomic", () => ["groupByAttribute"]),
8709
+ describe: (op) => op.value ? `Regroupe par ${op.value} en kanban` : "Retire le regroupement, retour en table"
8710
+ });
8187
8711
  var setFilters = setOnTab(
8188
8712
  "set_filters",
8189
8713
  "filters",
@@ -8235,7 +8759,8 @@ var setDefaultFilters = defineOperation({
8235
8759
  }
8236
8760
  return { ...view, config: { ...view.config, defaultFilters: op.filters } };
8237
8761
  }),
8238
- focus: (op) => ({ viewId: op.viewId }),
8762
+ focus: viewFocus2,
8763
+ presentation: definePresentation(viewFocus2, "atomic", () => ["config", "defaultFilters"]),
8239
8764
  describe: (op) => op.filters ? "Modifie les filtres de la vue" : "Retire les filtres de la vue"
8240
8765
  });
8241
8766
  var LIST_VIEW_OPERATIONS = [
@@ -8260,11 +8785,27 @@ function requireObject(state, objectId) {
8260
8785
  throw new ValidationError(`Object "${objectId}" is not in the draftable state`, []);
8261
8786
  }
8262
8787
  }
8263
- var objectOperationBase = { ...operationBase, objectId: z.string().min(1) };
8788
+ function objectFocus(op) {
8789
+ return { objectId: op.objectId };
8790
+ }
8791
+ function recordFocus(op) {
8792
+ return { objectId: op.objectId, recordId: op.recordId };
8793
+ }
8794
+ function attributeFocus(op) {
8795
+ return { objectId: op.objectId, attributeId: op.attributeId };
8796
+ }
8797
+ function firstChangedProperty3(op) {
8798
+ const keys = Object.keys(op.changes).sort();
8799
+ return keys.length === 1 ? [keys[0]] : void 0;
8800
+ }
8801
+ var objectOperationBase = { ...operationBase, objectId: z.string().uuid() };
8264
8802
  var addObjectSchema = z.object({
8265
8803
  ...objectOperationBase,
8266
8804
  type: z.literal("add_object"),
8267
- name: z.string().min(1),
8805
+ // The service's own kebab-case rule, enforced at APPEND: an agent that
8806
+ // names an object "Facture" is refused here with the format spelled out,
8807
+ // not at publish (live QA, 2026-08-17).
8808
+ name: OBJECT_NAME_SCHEMA,
8268
8809
  label: z.string().min(1),
8269
8810
  icon: z.string().min(1).optional()
8270
8811
  });
@@ -8288,7 +8829,8 @@ var addObject = defineOperation({
8288
8829
  },
8289
8830
  // The caller generates objectId, so a draft object is addressable by route
8290
8831
  // before it exists — that is what lets the app navigate to it live.
8291
- focus: (op) => ({ objectId: op.objectId }),
8832
+ focus: objectFocus,
8833
+ presentation: definePresentation(objectFocus, "structural"),
8292
8834
  describe: (op) => `Cr\xE9e l'objet \xAB ${op.label} \xBB`
8293
8835
  });
8294
8836
  var updateObjectSchema = z.object({
@@ -8296,6 +8838,9 @@ var updateObjectSchema = z.object({
8296
8838
  type: z.literal("update_object"),
8297
8839
  changes: z.object({ label: z.string().min(1).optional(), icon: z.string().min(1).optional() }).refine((c) => Object.keys(c).length > 0, "update_object needs at least one change")
8298
8840
  });
8841
+ var updateObjectFocus = (op) => ({
8842
+ objectId: op.objectId
8843
+ });
8299
8844
  var updateObject = defineOperation({
8300
8845
  type: "update_object",
8301
8846
  schema: updateObjectSchema,
@@ -8306,7 +8851,8 @@ var updateObject = defineOperation({
8306
8851
  objects: state.objects.map((o) => o.id === op.objectId ? { ...o, ...op.changes } : o)
8307
8852
  };
8308
8853
  },
8309
- focus: (op) => ({ objectId: op.objectId }),
8854
+ focus: updateObjectFocus,
8855
+ presentation: definePresentation(updateObjectFocus, "atomic", firstChangedProperty3),
8310
8856
  describe: (op) => op.changes.label ? `Renomme l'objet en \xAB ${op.changes.label} \xBB` : "Modifie l'objet"
8311
8857
  });
8312
8858
  var removeObjectSchema = z.object({ ...objectOperationBase, type: z.literal("remove_object") });
@@ -8324,16 +8870,42 @@ var removeObject = defineOperation({
8324
8870
  views: state.views.filter((v) => v.objectName !== objectName)
8325
8871
  };
8326
8872
  },
8327
- focus: () => ({}),
8873
+ focus: objectFocus,
8874
+ presentation: definePresentation(objectFocus, "structural"),
8328
8875
  describe: (op) => `Supprime l'objet ${op.objectId}`
8329
8876
  });
8877
+ var DRAFTABLE_ATTRIBUTE_TYPES = ATTRIBUTE_TYPES.filter(
8878
+ (type) => type !== "formula" && type !== "rollup"
8879
+ );
8330
8880
  var addAttributeSchema = z.object({
8331
8881
  ...objectOperationBase,
8332
8882
  type: z.literal("add_attribute"),
8333
8883
  attributeId: z.string().min(1),
8334
- name: z.string().min(1),
8884
+ // The same identifier rule the attribute builder enforces.
8885
+ name: ATTRIBUTE_NAME_SCHEMA,
8335
8886
  label: z.string().min(1),
8336
- attributeType: z.string().min(1)
8887
+ // The canonical union, not a bare string: an agent that invents "num" gets
8888
+ // refused at APPEND, where the error names the valid types and the one
8889
+ // operation to fix — instead of a whole draft failing at publish.
8890
+ attributeType: z.enum(DRAFTABLE_ATTRIBUTE_TYPES),
8891
+ /** Type-specific configuration, published as-is onto the attribute. */
8892
+ config: z.record(z.string(), z.unknown()).optional()
8893
+ }).superRefine((op, ctx) => {
8894
+ try {
8895
+ parseAttributeConfigForCreate(op.attributeType, op.config ?? {});
8896
+ } catch (error) {
8897
+ if (error instanceof ValidationError) {
8898
+ for (const detail of error.errors) {
8899
+ ctx.addIssue({
8900
+ code: "custom",
8901
+ message: detail.message,
8902
+ path: ["config", ...detail.path ?? []]
8903
+ });
8904
+ }
8905
+ return;
8906
+ }
8907
+ throw error;
8908
+ }
8337
8909
  });
8338
8910
  var addAttribute = defineOperation({
8339
8911
  type: "add_attribute",
@@ -8346,21 +8918,24 @@ var addAttribute = defineOperation({
8346
8918
  []
8347
8919
  );
8348
8920
  }
8921
+ const added = {
8922
+ id: op.attributeId,
8923
+ objectId: op.objectId,
8924
+ name: op.name,
8925
+ label: op.label,
8926
+ attributeType: op.attributeType,
8927
+ ...op.config === void 0 ? {} : { config: op.config }
8928
+ };
8929
+ for (const sample of state.sampleRecords) {
8930
+ if (sample.objectId === op.objectId) assertRequiredCovered(sample.id, added, sample.values);
8931
+ }
8349
8932
  return {
8350
8933
  ...state,
8351
- attributes: [
8352
- ...state.attributes,
8353
- {
8354
- id: op.attributeId,
8355
- objectId: op.objectId,
8356
- name: op.name,
8357
- label: op.label,
8358
- attributeType: op.attributeType
8359
- }
8360
- ]
8934
+ attributes: [...state.attributes, added]
8361
8935
  };
8362
8936
  },
8363
- focus: (op) => ({ objectId: op.objectId }),
8937
+ focus: attributeFocus,
8938
+ presentation: definePresentation(attributeFocus, "local"),
8364
8939
  describe: (op) => `Ajoute l'attribut \xAB ${op.label} \xBB`
8365
8940
  });
8366
8941
  var updateAttributeSchema = z.object({
@@ -8386,7 +8961,8 @@ var updateAttribute = defineOperation({
8386
8961
  // Carries objectId so the scope can load the attribute's parent. Without it
8387
8962
  // the reader returns an empty state and the fold rejects the operation before
8388
8963
  // the draft is ever persisted — renaming an existing field was impossible.
8389
- focus: (op) => ({ objectId: op.objectId }),
8964
+ focus: attributeFocus,
8965
+ presentation: definePresentation(attributeFocus, "atomic"),
8390
8966
  describe: (op) => op.changes.label ? `Renomme l'attribut en \xAB ${op.changes.label} \xBB` : "Modifie l'attribut"
8391
8967
  });
8392
8968
  var removeAttributeSchema = z.object({
@@ -8398,19 +8974,62 @@ var removeAttribute = defineOperation({
8398
8974
  type: "remove_attribute",
8399
8975
  schema: removeAttributeSchema,
8400
8976
  apply: (state, op) => {
8401
- if (!state.attributes.some((a) => a.id === op.attributeId)) {
8977
+ const removed = state.attributes.find((a) => a.id === op.attributeId);
8978
+ if (!removed) {
8402
8979
  throw new ValidationError(`Attribute "${op.attributeId}" is not in the draftable state`, []);
8403
8980
  }
8981
+ const user2 = state.sampleRecords.find(
8982
+ (r) => r.objectId === removed.objectId && removed.name in r.values
8983
+ );
8984
+ if (user2) {
8985
+ throw new ValidationError(
8986
+ `Attribute "${removed.name}" is still used by sample record "${user2.id}"`,
8987
+ []
8988
+ );
8989
+ }
8404
8990
  return { ...state, attributes: state.attributes.filter((a) => a.id !== op.attributeId) };
8405
8991
  },
8406
8992
  // Same reason as update_attribute: the parent object must be in scope.
8407
- focus: (op) => ({ objectId: op.objectId }),
8993
+ focus: attributeFocus,
8994
+ presentation: definePresentation(attributeFocus, "local"),
8408
8995
  describe: (op) => `Supprime l'attribut ${op.attributeId}`
8409
8996
  });
8997
+ function assertSampleValue(recordId, key, attribute, value) {
8998
+ const reconstructed = {
8999
+ id: attribute.id,
9000
+ name: attribute.name,
9001
+ label: attribute.label,
9002
+ type: attribute.attributeType,
9003
+ ...attribute.config
9004
+ };
9005
+ try {
9006
+ createAttributeValidator(reconstructed);
9007
+ } catch {
9008
+ return;
9009
+ }
9010
+ const result = validateAttribute(reconstructed, value);
9011
+ if (result.success) return;
9012
+ const errors = result.errors ?? [];
9013
+ const detail = errors.map((error) => error.message).join(", ");
9014
+ throw new ValidationError(
9015
+ `Sample record "${recordId}" has an invalid value for "${key}": ${detail}`,
9016
+ errors.map((error) => ({ path: error.path, message: error.message }))
9017
+ );
9018
+ }
9019
+ function assertRequiredCovered(recordId, attribute, values) {
9020
+ if (attribute.config?.required !== true) return;
9021
+ if (attribute.config?.defaultValue !== void 0) return;
9022
+ if (attribute.name in values && values[attribute.name] !== void 0) return;
9023
+ throw new ValidationError(
9024
+ `Sample record "${recordId}" is missing a value for required attribute "${attribute.name}"`,
9025
+ []
9026
+ );
9027
+ }
8410
9028
  var addSampleRecordSchema = z.object({
8411
9029
  ...objectOperationBase,
8412
9030
  type: z.literal("add_sample_record"),
8413
- recordId: z.string().min(1),
9031
+ // Same rule as objectId: publish inserts it, so it must be a UUID.
9032
+ recordId: z.string().uuid(),
8414
9033
  values: z.record(z.string(), z.unknown())
8415
9034
  });
8416
9035
  var addSampleRecord = defineOperation({
@@ -8421,6 +9040,22 @@ var addSampleRecord = defineOperation({
8421
9040
  if (state.sampleRecords.some((r) => r.id === op.recordId)) {
8422
9041
  throw new ValidationError(`Sample record "${op.recordId}" already exists`, []);
8423
9042
  }
9043
+ const known = new Map(
9044
+ state.attributes.filter((a) => a.objectId === op.objectId).map((a) => [a.name, a])
9045
+ );
9046
+ for (const [key, value] of Object.entries(op.values)) {
9047
+ const attribute = known.get(key);
9048
+ if (!attribute) {
9049
+ throw new ValidationError(
9050
+ `Sample record "${op.recordId}" uses unknown attribute "${key}"`,
9051
+ []
9052
+ );
9053
+ }
9054
+ assertSampleValue(op.recordId, key, attribute, value);
9055
+ }
9056
+ for (const attribute of known.values()) {
9057
+ assertRequiredCovered(op.recordId, attribute, op.values);
9058
+ }
8424
9059
  return {
8425
9060
  ...state,
8426
9061
  sampleRecords: [
@@ -8431,11 +9066,12 @@ var addSampleRecord = defineOperation({
8431
9066
  },
8432
9067
  // A sample is a draft record, not a render-time fiction: publishing
8433
9068
  // materialises it, discarding the draft discards it.
8434
- focus: (op) => ({ objectId: op.objectId, recordId: op.recordId }),
9069
+ focus: recordFocus,
9070
+ presentation: definePresentation(recordFocus, "local"),
8435
9071
  describe: () => "Ajoute un exemple"
8436
9072
  });
8437
9073
  var removeSampleRecordSchema = z.object({
8438
- ...operationBase,
9074
+ ...objectOperationBase,
8439
9075
  type: z.literal("remove_sample_record"),
8440
9076
  recordId: z.string().min(1)
8441
9077
  });
@@ -8443,12 +9079,16 @@ var removeSampleRecord = defineOperation({
8443
9079
  type: "remove_sample_record",
8444
9080
  schema: removeSampleRecordSchema,
8445
9081
  apply: (state, op) => {
8446
- if (!state.sampleRecords.some((r) => r.id === op.recordId)) {
8447
- throw new ValidationError(`Sample record "${op.recordId}" is not in the draft`, []);
9082
+ if (!state.sampleRecords.some((r) => r.id === op.recordId && r.objectId === op.objectId)) {
9083
+ throw new ValidationError(
9084
+ `Sample record "${op.recordId}" is not in object "${op.objectId}"`,
9085
+ []
9086
+ );
8448
9087
  }
8449
9088
  return { ...state, sampleRecords: state.sampleRecords.filter((r) => r.id !== op.recordId) };
8450
9089
  },
8451
- focus: () => ({}),
9090
+ focus: recordFocus,
9091
+ presentation: definePresentation(recordFocus, "local"),
8452
9092
  describe: () => "Retire un exemple"
8453
9093
  });
8454
9094
  var SCHEMA_OPERATIONS = [
@@ -8524,6 +9164,26 @@ function parseOperation(candidate) {
8524
9164
  }
8525
9165
  return parsed.data;
8526
9166
  }
9167
+ function toJsonSchema(schema) {
9168
+ return z.toJSONSchema(schema, { io: "input" });
9169
+ }
9170
+ function describeOperationInput(type) {
9171
+ const definition = OPERATION_REGISTRY.get(type);
9172
+ if (!definition) {
9173
+ throw new ValidationError(`Unknown operation type "${type}"`, []);
9174
+ }
9175
+ return toJsonSchema(definition.schema);
9176
+ }
9177
+ function describeAttributeConfig(type) {
9178
+ const draftable = DRAFTABLE_ATTRIBUTE_TYPES.find((candidate) => candidate === type);
9179
+ if (!draftable) {
9180
+ throw new ValidationError(`Unknown attribute type "${type}"`, []);
9181
+ }
9182
+ return toJsonSchema(getAttributeConfigWriteSchema(draftable));
9183
+ }
9184
+ function listDescribableNames() {
9185
+ return { operations: [...ALL_OPERATION_TYPES], attributeTypes: [...DRAFTABLE_ATTRIBUTE_TYPES] };
9186
+ }
8527
9187
 
8528
9188
  // src/architect/field-ids.ts
8529
9189
  function makeFieldId(groupId, seed, collisionIndex) {
@@ -8552,6 +9212,96 @@ function ensureFieldIds(tabs) {
8552
9212
  );
8553
9213
  }
8554
9214
 
9215
+ // src/architect/presentation.ts
9216
+ function presentationOf(operation) {
9217
+ return defOf(operation).presentation(operation);
9218
+ }
9219
+ function episodeImpactOf(operations) {
9220
+ const presentations = operations.map(presentationOf);
9221
+ const roots = new Set(
9222
+ presentations.map(({ focus }) => focus.viewId ?? focus.objectId).filter((root) => root !== void 0)
9223
+ );
9224
+ if (roots.size > 1) return "structural";
9225
+ if (presentations.some(({ impact }) => impact === "structural")) return "structural";
9226
+ if (presentations.some(({ impact }) => impact === "local")) return "local";
9227
+ return "atomic";
9228
+ }
9229
+ function listTabOf(view, tabId) {
9230
+ return view.config.tabs?.find((tab) => tab.id === tabId);
9231
+ }
9232
+ function snapshotArchitectTarget(state, focus) {
9233
+ const view = focus.viewId ? state.views.find((candidate) => candidate.id === focus.viewId) : void 0;
9234
+ const detailTab = focus.tabId ? view?.tabs.find((candidate) => candidate.id === focus.tabId) : void 0;
9235
+ if (focus.attributeId) {
9236
+ return state.attributes.find((attribute) => attribute.id === focus.attributeId);
9237
+ }
9238
+ if (focus.fieldId) {
9239
+ if (detailTab?.type !== "form") return void 0;
9240
+ for (const group2 of detailTab.groups) {
9241
+ const field = group2.fields.find((candidate) => candidate.id === focus.fieldId);
9242
+ if (field) return field;
9243
+ }
9244
+ return void 0;
9245
+ }
9246
+ if (focus.groupId) {
9247
+ if (detailTab?.type !== "form") return void 0;
9248
+ return detailTab.groups.find((candidate) => candidate.id === focus.groupId);
9249
+ }
9250
+ if (focus.tabId) {
9251
+ if (!view) return void 0;
9252
+ return detailTab ?? listTabOf(view, focus.tabId);
9253
+ }
9254
+ if (focus.recordId) {
9255
+ return state.sampleRecords.find((record) => record.id === focus.recordId);
9256
+ }
9257
+ if (view) return view;
9258
+ if (focus.objectId) {
9259
+ return state.objects.find((object2) => object2.id === focus.objectId);
9260
+ }
9261
+ return void 0;
9262
+ }
9263
+ function deriveArchitectChanges(initial, operations) {
9264
+ let state = initial;
9265
+ return operations.map((operation) => {
9266
+ const presentation = presentationOf(operation);
9267
+ const before = snapshotArchitectTarget(state, presentation.focus);
9268
+ state = applyOperations(state, [operation]);
9269
+ const after = snapshotArchitectTarget(state, presentation.focus);
9270
+ return {
9271
+ operationId: operation.id,
9272
+ operationType: operation.type,
9273
+ presentation,
9274
+ before,
9275
+ after
9276
+ };
9277
+ });
9278
+ }
9279
+
9280
+ // src/architect/object-projection.ts
9281
+ function toDraftableObject(object2) {
9282
+ return {
9283
+ id: object2.id ?? object2.name,
9284
+ name: object2.name,
9285
+ label: object2.label,
9286
+ ...object2.icon === void 0 ? {} : { icon: object2.icon }
9287
+ };
9288
+ }
9289
+ function toDraftableAttributes(object2) {
9290
+ const objectId = object2.id ?? object2.name;
9291
+ return (object2.attributes ?? []).map((attribute) => toDraftableAttribute(attribute, objectId));
9292
+ }
9293
+ function toDraftableAttribute(attribute, objectId) {
9294
+ const { id: _id, name: _name, label: _label, type: _type, ...config } = attribute;
9295
+ return {
9296
+ id: attribute.id ?? attribute.name,
9297
+ objectId,
9298
+ name: attribute.name,
9299
+ label: attribute.label ?? attribute.name,
9300
+ attributeType: attribute.type,
9301
+ config
9302
+ };
9303
+ }
9304
+
8555
9305
  // src/architect/view-projection.ts
8556
9306
  function toDraftableView(view) {
8557
9307
  return {
@@ -8581,4 +9331,4 @@ function fromDraftableView(original, drafted) {
8581
9331
  };
8582
9332
  }
8583
9333
 
8584
- export { AGENT_UI_BATCH_MAX_BYTES, AGENT_UI_BATCH_MAX_ITEMS, ALLOWED_PROPERTY_TYPES, ALL_ACTIONS, ALL_OPERATION_TYPES, ALL_SYSTEM_RESOURCES, AUDIT_ACTIONS, AUDIT_RESOURCE_TYPES, ActivityTabConfig, AgentBuilder, BEHAVIOR_PROPERTIES, BROWSER_PREVIEW_STATUSES, BYTE_UNIT_LABELS, CLAIMABLE_SESSION_STATUSES, COMPUTED_FUNCTIONS, COMPUTED_FUNCTION_METADATA, COMPUTED_FUNCTION_NAMES, CONNECTOR_CALLBACK_PARAM, COUNT_MODES, ComputedFormulaCompileError, CustomTabConfig, DB_COLUMN_FIELDS, DEFAULT_AGENT_EXECUTION_CONFIG, DEFAULT_APPROVAL_POLICY, DEFAULT_LABEL_FALLBACK, DEFAULT_ROLES, DEFAULT_ROLE_DESCRIPTIONS, DEFAULT_ROLE_LABELS, DEFAULT_ROLE_PERMISSIONS, DOCUMENT_SYSTEM_ATTRIBUTES, DRIVE_LIST_VIEW, DRIVE_OBJECT, DRIVE_OBJECT_NAME, DRIVE_VIEW, 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, 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, MeetingsTabConfig, NATIVE_AGENT_UI_PART_IDS_METADATA_KEY, NATIVE_AGENT_UI_PART_IDS_METADATA_SCHEMA_VERSION, 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, OPEN_TOOL_PART_STATES, OPERATION_REGISTRY, OPERATOR_SPECS, ObjectBuilder, PRESENTATION_PROPERTIES, QUALIFIED_SEPARATOR, RECORD_CREATOR_ROOT_ACTOR_METADATA_KEY, RELATION_TARGET_ANY, 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, TOOL_APPROVAL_STATES, TabBuilder, TableTabConfig, USER_STATUSES, USER_WORK_POSTURES, accessLevelToActions, actionsToAccessLevel, agent, agentDisplayName, applyOperations, applyPipes, applyRelationProps, assertAcyclicComputedDependencies, booleanFlag, buildAgentFallbackTitle, buildPermissionFlags, buildPropertySchema, buildQualifiedAttribute, checkbox, compileComputedFormula, compileRollupAttribute, computeByteMagnitude, conversationDisplayTitle, createFlagRegistry, createFlagService, createStandardSchemaProps, currency, date, dateInTimezone, dateValueStart, defineOperation, deriveInitials, describeOperations, destructiveSchema, detailView, document, ensureFieldIds, evaluateComputedAst, evaluateComputedFormula, evaluateComputedFormulaWithResult, evaluateFilterState, evaluateRecordFilterState, extractAttributeNames, extractValueRefs, flagRegistry, focusOf, form, formFieldFlatKey, formFieldKey, formRegistry, formatAttributeValue, formatByteSize, formatComputedResult, formatLocationValue, formula, fromDraftableView, generateDefaultDetailView, generateDefaultListView, getActiveTab, getErrorMessage, getLiveProtocolPayloadChannel, getRecordCreatorPrincipalId, getSlotFieldTargets, getUserDisplayName, group, hasDestructiveEntries, hasOptions, includesAction, inferInverseCardinality, inferRollupReturnType, isAgentUIMessageBatch, isAttributeSortable2 as isAttributeSortable, isBilateralRelation, isCheckboxEquality, isClaimableSessionStatus, isComputedFunctionName, isDateRangeValue, isDefaultRole, isDetailView, isDocumentAttribute, isEmptyObject, isFieldGroup, isFormDefinition, isFormFieldsRow, isFormFreeFieldRef, isFormHeadingRow, isFormSeparatorRow, isFormSlotFieldRef, isFormTextRow, isLabelExpression, isListView, isLiveEventEnvelope, isLiveEventPayload, isLiveEventPayloadForType, isLiveEventType, isNotEmpty, isOpenToolPartState, isPlainRecord2 as isPlainRecord, isStandardSchema, isTerminalSessionStatus, isTerminalState, isToolApprovalState, isUniversalRelation, jsonFlag, legacyStatusToSessionState, listView, liveChannelKey, location, makeFieldId, matchesAccepts, multiselect, nativeAgentUIPartIdMetadataKey, normalizeDateValue, number, numberFlag, object, parseCountMode, parseLiveChannelKey, parseNativeAgentUIPartIdsMetadata, parseOperation, parseOptionalCountMode, parseQualifiedAttribute, persistedDefaultViewTargetSchema, persistedSchemaPlanSchema, phone, plannedAttributeSchema, plannedInlineAttributeSchema, plannedObjectSchema, proposedDefaultViewTargetSchema, qualifiedPropertyDefs, readFormFieldValue, registry, relation, relationPropertyDefs, renderLabelExpression, resetViewToDefault, resolveAttributeDefaultValue, resolveFieldRequired, resolvePropertyDefinitions, richtext, rollup, rollupToFormulaExpression, schemaPlanSchema, select, sessionStateToLegacyStatus, status, stringFlag, text, toDraftableView, toUndefinedIfEmpty, user, validateAttributeName, validateLabelExpression, validateObjectName, validateViewName, viewRegistry, viewStateKey, viewSyncPayload };
9334
+ export { AGENT_UI_BATCH_MAX_BYTES, AGENT_UI_BATCH_MAX_ITEMS, ALLOWED_PROPERTY_TYPES, ALL_ACTIONS, ALL_OPERATION_TYPES, ALL_SYSTEM_RESOURCES, ATTRIBUTE_TYPES, AUDIT_ACTIONS, AUDIT_RESOURCE_TYPES, ActivityTabConfig, AgentBuilder, BEHAVIOR_PROPERTIES, BROWSER_PREVIEW_STATUSES, BYTE_UNIT_LABELS, CLAIMABLE_SESSION_STATUSES, COMPUTED_FUNCTIONS, COMPUTED_FUNCTION_METADATA, COMPUTED_FUNCTION_NAMES, CONNECTOR_CALLBACK_PARAM, COUNT_MODES, ComputedFormulaCompileError, CustomTabConfig, DB_COLUMN_FIELDS, DEFAULT_AGENT_EXECUTION_CONFIG, DEFAULT_APPROVAL_POLICY, DEFAULT_LABEL_FALLBACK, DEFAULT_ROLES, DEFAULT_ROLE_DESCRIPTIONS, DEFAULT_ROLE_LABELS, DEFAULT_ROLE_PERMISSIONS, DOCUMENT_SYSTEM_ATTRIBUTES, DRAFTABLE_ATTRIBUTE_TYPES, DRIVE_LIST_VIEW, DRIVE_OBJECT, DRIVE_OBJECT_NAME, DRIVE_VIEW, 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, 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, MeetingsTabConfig, NATIVE_AGENT_UI_PART_IDS_METADATA_KEY, NATIVE_AGENT_UI_PART_IDS_METADATA_SCHEMA_VERSION, 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, OBJECT_NAME_SCHEMA, OPEN_TOOL_PART_STATES, OPERATION_REGISTRY, OPERATOR_SPECS, ObjectBuilder, PRESENTATION_PROPERTIES, QUALIFIED_SEPARATOR, RECORD_CREATOR_ROOT_ACTOR_METADATA_KEY, RELATION_TARGET_ANY, 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, TOOL_APPROVAL_STATES, TabBuilder, TableTabConfig, UPDATE_TABLE_TAB_CHANGE_KEYS, UPDATE_TAB_CHANGE_KEYS, UPDATE_TAB_CONFIG_CHANGE_KEYS, USER_STATUSES, USER_WORK_POSTURES, accessLevelToActions, actionsToAccessLevel, agent, agentDataChunk, agentDisplayName, agentMessageAttachmentSchema, agentMessagePartSchema, agentSessionMessageSchema, agentUIValidationError, applyOperations, applyPipes, applyRelationProps, assertAcyclicComputedDependencies, assertCustomAgentUIMessageChunk, booleanFlag, buildAgentFallbackTitle, buildPermissionFlags, buildPropertySchema, buildQualifiedAttribute, checkbox, compareAgentSessionMessages, compileComputedFormula, compileRollupAttribute, computeByteMagnitude, conversationDisplayTitle, createFlagRegistry, createFlagService, createStandardSchemaProps, currency, customDataChunkSchemas, date, dateInTimezone, dateValueStart, defineOperation, definePresentation, deriveArchitectChanges, deriveInitials, describeAttributeConfig, describeOperationInput, describeOperations, destructiveSchema, detailView, document, durableDateSchema, ensureFieldIds, episodeImpactOf, evaluateComputedAst, evaluateComputedFormula, evaluateComputedFormulaWithResult, evaluateFilterState, evaluateRecordFilterState, extractAttributeNames, extractValueRefs, flagRegistry, focusOf, form, formFieldFlatKey, formFieldKey, formRegistry, formatAttributeValue, formatByteSize, formatComputedResult, formatLocationValue, formula, fromDraftableView, generateDefaultDetailView, generateDefaultListView, getActiveTab, getErrorMessage, getLiveProtocolPayloadChannel, getRecordCreatorPrincipalId, getSlotFieldTargets, getUserDisplayName, group, hasDestructiveEntries, hasOptions, includesAction, inferInverseCardinality, inferRollupReturnType, isAgentUIDataName, isAgentUIMessageBatch, isAttributeSortable2 as isAttributeSortable, isBilateralRelation, isCheckboxEquality, isClaimableSessionStatus, isComputedFunctionName, isDateRangeValue, isDefaultRole, isDetailView, isDocumentAttribute, isEmptyObject, isFieldGroup, isFormDefinition, isFormFieldsRow, isFormFreeFieldRef, isFormHeadingRow, isFormSeparatorRow, isFormSlotFieldRef, isFormTextRow, isLabelExpression, isListView, isLiveEventEnvelope, isLiveEventPayload, isLiveEventPayloadForType, isLiveEventType, isNotEmpty, isOpenToolPartState, isPlainRecord2 as isPlainRecord, isStandardSchema, isTerminalSessionStatus, isTerminalState, isToolApprovalState, isUniversalRelation, jsonFlag, legacyStatusToSessionState, listDescribableNames, listView, liveChannelKey, location, makeFieldId, matchesAccepts, mentionReferenceSchema, modelDefinitionSchema, multiselect, nativeAgentUIPartIdMetadataKey, normalizeDateValue, number, numberFlag, object, orderAgentSessionMessages, parseCountMode, parseLiveChannelKey, parseNativeAgentUIPartIdsMetadata, parseOperation, parseOptionalCountMode, parseQualifiedAttribute, persistedDefaultViewTargetSchema, persistedSchemaPlanSchema, phone, plannedAttributeSchema, plannedInlineAttributeSchema, plannedObjectSchema, presentationOf, proposedDefaultViewTargetSchema, qualifiedPropertyDefs, readFormFieldValue, registry, relation, relationPropertyDefs, renderLabelExpression, resetViewToDefault, resolveAttributeDefaultValue, resolveFieldRequired, resolvePropertyDefinitions, richtext, rollup, rollupToFormulaExpression, schemaPlanSchema, select, sessionStateToLegacyStatus, status, stringFlag, text, toDraftableAttributes, toDraftableObject, toDraftableView, toUndefinedIfEmpty, todoItemSchema, todoPlanSchema, toolImpactSchema, user, validateAttributeName, validateLabelExpression, validateObjectName, validateViewName, viewRegistry, viewStateKey, viewSyncPayload };