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

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 (75) hide show
  1. package/dist/{all-Ig0ig9wp.d.ts → all-C3EaFLCU.d.ts} +7 -17
  2. package/dist/{all-C0hXd79K.d.mts → all-CQMswOrw.d.mts} +7 -17
  3. package/dist/{attributes-D8eHv5Kf.d.ts → attributes-CU871AfG.d.ts} +12 -12
  4. package/dist/{attributes--M1ifW8_.d.mts → attributes-DoiGyNFk.d.mts} +12 -12
  5. package/dist/{chunk-FAEOVIDJ.js → chunk-DIMTNM3F.js} +7 -3
  6. package/dist/{chunk-NUEIGMYS.mjs → chunk-EFSS7PGC.mjs} +1 -1
  7. package/dist/{chunk-XDA5PZRT.mjs → chunk-HOVUEYEQ.mjs} +34 -0
  8. package/dist/{chunk-MXYCCUNB.js → chunk-KIMECN6D.js} +68 -44
  9. package/dist/{chunk-M3WFXOA4.js → chunk-L4KLYMUI.js} +34 -0
  10. package/dist/{chunk-XTBGGJ3G.js → chunk-LBGLB443.js} +3 -3
  11. package/dist/{chunk-PUMM6SPY.mjs → chunk-PLTLAMWJ.mjs} +1 -1
  12. package/dist/{chunk-TBAD2T7Q.mjs → chunk-QGRYOIHT.mjs} +37 -13
  13. package/dist/{chunk-MSIGO7JA.mjs → chunk-R34LOMT7.mjs} +5 -1
  14. package/dist/{chunk-3PGLMGTR.js → chunk-V4MZOTLV.js} +4 -4
  15. package/dist/exceptions.d.mts +22 -3
  16. package/dist/exceptions.d.ts +22 -3
  17. package/dist/exceptions.js +39 -39
  18. package/dist/exceptions.mjs +1 -1
  19. package/dist/{helpers-DyoPqiSz.d.ts → helpers-BNr-Dppk.d.ts} +3 -3
  20. package/dist/{helpers-BiABdSxK.d.mts → helpers-CfEOUBmB.d.mts} +3 -3
  21. package/dist/{index-SpFpkWVC.d.ts → index-Br7koyHF.d.ts} +53 -27
  22. package/dist/{index-C3P5Dnwt.d.mts → index-D9XBjFnu.d.mts} +53 -27
  23. package/dist/index.d.mts +568 -151
  24. package/dist/index.d.ts +568 -151
  25. package/dist/index.js +1389 -292
  26. package/dist/index.mjs +1174 -99
  27. package/dist/{migrations-B1kkIhIX.d.ts → migrations-BGWgXHXb.d.ts} +1 -1
  28. package/dist/{migrations-BNlQVzDC.d.mts → migrations-C-GN1xx_.d.mts} +1 -1
  29. package/dist/{objects-DmMqHn3L.d.mts → objects-BRypaBpi.d.mts} +2 -4
  30. package/dist/{objects-DgFojgwH.d.ts → objects-BiOMwzLL.d.ts} +2 -4
  31. package/dist/{types-DHqXzkgW.d.mts → types-80c2rOUZ.d.mts} +1 -1
  32. package/dist/{types-DYYFto8d.d.ts → types-DqYz8Iv_.d.ts} +1 -1
  33. package/dist/utils.js +8 -8
  34. package/dist/utils.mjs +2 -2
  35. package/dist/validation/all.d.mts +7 -7
  36. package/dist/validation/all.d.ts +7 -7
  37. package/dist/validation/all.js +29 -29
  38. package/dist/validation/all.mjs +4 -4
  39. package/dist/validation/complex/currency.d.mts +2 -2
  40. package/dist/validation/complex/currency.d.ts +2 -2
  41. package/dist/validation/complex/location.d.mts +2 -2
  42. package/dist/validation/complex/location.d.ts +2 -2
  43. package/dist/validation/complex/phone.d.mts +2 -2
  44. package/dist/validation/complex/phone.d.ts +2 -2
  45. package/dist/validation/complex/relation.d.mts +2 -2
  46. package/dist/validation/complex/relation.d.ts +2 -2
  47. package/dist/validation/complex/richtext.d.mts +2 -2
  48. package/dist/validation/complex/richtext.d.ts +2 -2
  49. package/dist/validation/complex/select.d.mts +2 -2
  50. package/dist/validation/complex/select.d.ts +2 -2
  51. package/dist/validation/complex/user.d.mts +2 -2
  52. package/dist/validation/complex/user.d.ts +2 -2
  53. package/dist/validation/computed/formula.d.mts +2 -2
  54. package/dist/validation/computed/formula.d.ts +2 -2
  55. package/dist/validation/computed/rollup.d.mts +2 -2
  56. package/dist/validation/computed/rollup.d.ts +2 -2
  57. package/dist/validation/config/index.d.mts +4 -4
  58. package/dist/validation/config/index.d.ts +4 -4
  59. package/dist/validation/config/index.js +11 -11
  60. package/dist/validation/config/index.mjs +2 -2
  61. package/dist/validation/core/index.d.mts +3 -3
  62. package/dist/validation/core/index.d.ts +3 -3
  63. package/dist/validation/object/index.d.mts +5 -5
  64. package/dist/validation/object/index.d.ts +5 -5
  65. package/dist/validation/object/index.js +14 -14
  66. package/dist/validation/object/index.mjs +2 -2
  67. package/dist/validation/primitives/checkbox.d.mts +2 -2
  68. package/dist/validation/primitives/checkbox.d.ts +2 -2
  69. package/dist/validation/primitives/date.d.mts +2 -2
  70. package/dist/validation/primitives/date.d.ts +2 -2
  71. package/dist/validation/primitives/number.d.mts +2 -2
  72. package/dist/validation/primitives/number.d.ts +2 -2
  73. package/dist/validation/primitives/text.d.mts +2 -2
  74. package/dist/validation/primitives/text.d.ts +2 -2
  75. package/package.json +2 -2
package/dist/index.mjs CHANGED
@@ -1,11 +1,11 @@
1
- import { canonicalStringify, generateId } from './chunk-NUEIGMYS.mjs';
2
- export { asTenantId, asUserId, canonicalStringify, deepEqual, generateId, indexBy } from './chunk-NUEIGMYS.mjs';
3
- import { SYSTEM_FILTER_ATTRIBUTE_TYPES, RESERVED_OBJECT_NAMES, listViewConfigSchema, detailViewConfigSchema, RESERVED_ATTRIBUTE_NAMES, isAttributeSortable, getAttributeCapabilities, resolveIsWithinBounds, normalizeForEdgeRpc, getOperatorPolarity, extractCurrencyFilterValue } from './chunk-TBAD2T7Q.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-TBAD2T7Q.mjs';
5
- import { iconNameSchema, parseAttributeConfigForCreate, parseComputedFormula } from './chunk-MSIGO7JA.mjs';
6
- export { ComputedFormulaParseError, SCHEMA_LIMITS, colorIdSchema, iconNameSchema, multiselectOptionWriteSchema, parseAttributeConfig, parseAttributeConfigForCreate, parseAttributeConfigForUpdate, parseComputedFormula, selectOptionWriteSchema, statusGroupSchema, statusOptionWriteSchema } from './chunk-MSIGO7JA.mjs';
7
- import { createObjectValidator, createAttributeValidator, isNullishOrEmptyString } from './chunk-PUMM6SPY.mjs';
8
- export { createFormAttributeValidator, isNullishOrEmptyString, isValuePresent, rejectUnknownAttributesOrThrow, validateDraft, validateDraftOrThrow, validateObject, validateObjectOrThrow } from './chunk-PUMM6SPY.mjs';
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';
9
9
  import './chunk-QVLQPW3O.mjs';
10
10
  import './chunk-ZDQ5AP26.mjs';
11
11
  import './chunk-LV3FEUKU.mjs';
@@ -15,8 +15,8 @@ export { createCheckboxValidator } from './chunk-OSSGN43B.mjs';
15
15
  export { createDateValidator } from './chunk-Q44QKLN4.mjs';
16
16
  export { createNumberValidator } from './chunk-UANQJ2GH.mjs';
17
17
  export { TEXT_FORMAT_PATTERNS, createTextValidator, resolveTextPattern } from './chunk-O73ROMWQ.mjs';
18
- import { SchemaError, SchemaErrorCode, ValidationError, DuplicateError, NotFoundError } from './chunk-XDA5PZRT.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-XDA5PZRT.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';
20
20
  import './chunk-AYVHMVKQ.mjs';
21
21
  import './chunk-YUFTHPOE.mjs';
22
22
  import { formatPhoneForDisplay, normalizeCountrylessPhoneNumber, normalizePhoneNumber } from './chunk-R5LAJCBU.mjs';
@@ -184,6 +184,18 @@ var SESSION_TERMINAL_STATUSES = [
184
184
  function isTerminalSessionStatus(status2) {
185
185
  return SESSION_TERMINAL_STATUSES.includes(status2);
186
186
  }
187
+ var CLAIMABLE_SESSION_STATUSES = [
188
+ "idle",
189
+ "completed",
190
+ "waiting_human",
191
+ "waiting_agents",
192
+ "cancelled",
193
+ "failed",
194
+ "timeout"
195
+ ];
196
+ function isClaimableSessionStatus(status2) {
197
+ return CLAIMABLE_SESSION_STATUSES.includes(status2);
198
+ }
187
199
  var DEFAULT_APPROVAL_POLICY = Object.freeze({
188
200
  mutation: "ask",
189
201
  destructive: "ask",
@@ -193,6 +205,18 @@ var TODO_PLAN_STATUSES = ["active", "completed", "abandoned"];
193
205
  function agentDisplayName(agent2) {
194
206
  return agent2.label?.trim() || agent2.name;
195
207
  }
208
+ var TOOL_APPROVAL_STATES = [
209
+ "approval-requested",
210
+ "approval-responded",
211
+ "approval-dispatched"
212
+ ];
213
+ var OPEN_TOOL_PART_STATES = ["streaming", "running", ...TOOL_APPROVAL_STATES];
214
+ function isOpenToolPartState(state) {
215
+ return OPEN_TOOL_PART_STATES.includes(state);
216
+ }
217
+ function isToolApprovalState(state) {
218
+ return TOOL_APPROVAL_STATES.includes(state);
219
+ }
196
220
  var TODO_STATUSES = ["pending", "in_progress", "completed", "blocked"];
197
221
  var MAX_TODOS = 50;
198
222
  var MAX_TODO_ID_CHARS = 80;
@@ -296,6 +320,15 @@ function resolveFieldRequired(input) {
296
320
  function getSlotFieldTargets(field) {
297
321
  return field.additionalSlotIds?.length ? [field.slotId, ...field.additionalSlotIds] : [field.slotId];
298
322
  }
323
+ function formFieldKey(field) {
324
+ return isFormSlotFieldRef(field) ? `${field.slotId}.${field.attribute}` : `free.${field.attribute.name}`;
325
+ }
326
+ function formFieldFlatKey(field) {
327
+ return isFormSlotFieldRef(field) ? field.attribute : field.attribute.name;
328
+ }
329
+ function readFormFieldValue(values, field) {
330
+ return values[formFieldKey(field)] ?? values[formFieldFlatKey(field)];
331
+ }
299
332
 
300
333
  // src/types/forms/rows.ts
301
334
  function isFormFieldsRow(row) {
@@ -375,9 +408,6 @@ function isListView(view) {
375
408
  function isFieldGroup(group2) {
376
409
  return group2.type === "fields";
377
410
  }
378
- function isRelationGroup(group2) {
379
- return group2.type === "relation";
380
- }
381
411
 
382
412
  // src/types/pagination.ts
383
413
  var COUNT_MODES = ["none", "estimated", "exact"];
@@ -386,8 +416,7 @@ function parseCountMode(value) {
386
416
  return value;
387
417
  }
388
418
  throw new ValidationError(
389
- // biome-ignore lint/style/useTemplate: see the comment above.
390
- "countMode must be one of: " + COUNT_MODES.join(", ") + " (received: " + String(value) + ")",
419
+ `countMode must be one of: ${COUNT_MODES.join(", ")} (received: ${String(value)})`,
391
420
  []
392
421
  );
393
422
  }
@@ -859,6 +888,12 @@ function relationPropertyDefs(attribute) {
859
888
  if (attribute?.type !== "relation") return void 0;
860
889
  return attribute.properties?.definitions;
861
890
  }
891
+ function qualifiedPropertyDefs(attribute) {
892
+ if (attribute?.type === "relation" || attribute?.type === "document") {
893
+ return attribute.properties?.definitions;
894
+ }
895
+ return void 0;
896
+ }
862
897
  function extractValueRefs(value) {
863
898
  if (isNullishOrEmptyString(value)) return [];
864
899
  if (typeof value === "string") return [{ id: value }];
@@ -2122,6 +2157,16 @@ var RollupAttributeBuilder = class extends BaseAttributeBuilder {
2122
2157
  this.attr.targetAttributeOptions = options;
2123
2158
  return this;
2124
2159
  }
2160
+ /**
2161
+ * Set the currency code a sum/avg over a currency target renders with
2162
+ * (#2644). Mirror of the target attribute's `defaultCurrency` — the stored
2163
+ * value stays a bare number; this only carries the symbol to the screen.
2164
+ * @param code - ISO 4217 code (e.g. "EUR")
2165
+ */
2166
+ targetCurrency(code) {
2167
+ this.attr.targetCurrencyCode = code;
2168
+ return this;
2169
+ }
2125
2170
  /**
2126
2171
  * Build the attribute, validating computed-field configuration eagerly so a
2127
2172
  * misconfiguration surfaces at schema-definition time (with a fix-it hint)
@@ -2798,6 +2843,21 @@ var ObjectBuilder = class {
2798
2843
  this.obj.metadata = { ...this.obj.metadata, order: value };
2799
2844
  return this;
2800
2845
  }
2846
+ /**
2847
+ * Hide this object from navigation surfaces — the sidebar data section and
2848
+ * the command palette, which already honour `metadata.hidden`. For objects
2849
+ * that own a dedicated surface: `drives` has the Drive page, so listing it
2850
+ * beside business objects would offer the same thing twice under two
2851
+ * different affordances.
2852
+ *
2853
+ * The object stays whole everywhere else: API, search, permissions, agent
2854
+ * tools, filters and record pages all continue to see it. This hides a
2855
+ * navigation entry; it never restricts access.
2856
+ */
2857
+ hidden() {
2858
+ this.obj.metadata = { ...this.obj.metadata, hidden: true };
2859
+ return this;
2860
+ }
2801
2861
  /**
2802
2862
  * Set the label expression template for displaying records
2803
2863
  * This is REQUIRED for every object.
@@ -3047,74 +3107,6 @@ var GroupBuilder = class {
3047
3107
  return this.data;
3048
3108
  }
3049
3109
  };
3050
- var RelationGroupBuilder = class {
3051
- constructor(id, label, attribute) {
3052
- this.data = { type: "relation" };
3053
- this.data.id = id;
3054
- this.data.label = label;
3055
- this.data.attribute = attribute;
3056
- }
3057
- /**
3058
- * Set group description
3059
- */
3060
- description(value) {
3061
- this.data.description = value;
3062
- return this;
3063
- }
3064
- /**
3065
- * Make group collapsible
3066
- * @param collapsed - Initial collapsed state (default: false)
3067
- */
3068
- collapsible(collapsed = false) {
3069
- this.data.collapsible = true;
3070
- this.data.collapsed = collapsed;
3071
- return this;
3072
- }
3073
- /**
3074
- * Set display order
3075
- */
3076
- order(value) {
3077
- this.data.order = value;
3078
- return this;
3079
- }
3080
- /**
3081
- * Set columns to display in the relations table
3082
- * @example .columns("name", "email", "phone")
3083
- */
3084
- columns(...names) {
3085
- this.data.columns = names;
3086
- return this;
3087
- }
3088
- /**
3089
- * Set the group as read-only (no add/remove/edit)
3090
- */
3091
- readOnly(value = true) {
3092
- this.data.readOnly = value;
3093
- return this;
3094
- }
3095
- /**
3096
- * Allow creating new related records inline
3097
- */
3098
- allowCreate(value = true) {
3099
- this.data.allowCreate = value;
3100
- return this;
3101
- }
3102
- /**
3103
- * Build the relation group definition
3104
- */
3105
- build() {
3106
- if (!this.data.id) {
3107
- throw new Error("[RelationGroupBuilder] id is required");
3108
- }
3109
- if (!this.data.label) {
3110
- throw new Error("[RelationGroupBuilder] label is required");
3111
- }
3112
- if (!this.data.attribute) {
3113
- throw new Error("[RelationGroupBuilder] attribute is required");
3114
- }
3115
- return this.data;
3116
- }
3117
- };
3118
3110
  var TableTabConfig = class {
3119
3111
  /** @internal */
3120
3112
  constructor(view, tabData) {
@@ -3465,7 +3457,7 @@ var TabBuilder = class {
3465
3457
  // ─────────────────────────────────────────────────────────────────────────
3466
3458
  /**
3467
3459
  * Create a form tab with groups
3468
- * @example .form(group("info", "Info").fields("name", "email"), relationGroup("contacts", "Contacts", "contacts"))
3460
+ * @example .form(group("info", "Info").fields("name", "email"))
3469
3461
  */
3470
3462
  form(...groups) {
3471
3463
  if (groups.length === 0) {
@@ -3476,9 +3468,7 @@ var TabBuilder = class {
3476
3468
  const tab = {
3477
3469
  ...this.base,
3478
3470
  type: "form",
3479
- groups: groups.map(
3480
- (g) => g instanceof GroupBuilder || g instanceof RelationGroupBuilder ? g.build() : g
3481
- )
3471
+ groups: groups.map((g) => g instanceof GroupBuilder ? g.build() : g)
3482
3472
  };
3483
3473
  return this.view._addTab(tab);
3484
3474
  }
@@ -4022,9 +4012,6 @@ function listView(name, label) {
4022
4012
  function group(id, label) {
4023
4013
  return new GroupBuilder(id, label);
4024
4014
  }
4025
- function relationGroup(id, label, attribute) {
4026
- return new RelationGroupBuilder(id, label, attribute);
4027
- }
4028
4015
 
4029
4016
  // src/feature-flags/flag-builder.ts
4030
4017
  function validateFlagName(name) {
@@ -4361,7 +4348,25 @@ var FlagService = class {
4361
4348
  * @returns Map of flag names to resolved values
4362
4349
  */
4363
4350
  async resolveAll(context = {}) {
4364
- const resolved = /* @__PURE__ */ new Map();
4351
+ const flagNames = this.collectFlagNames();
4352
+ const overrides = this.repository && flagNames.size > 0 ? await this.getAllOverrides(context, [...flagNames]) : emptyOverrides();
4353
+ return this.resolveNames(flagNames, overrides, context);
4354
+ }
4355
+ /**
4356
+ * Resolve every flag from static defaults only, never touching the
4357
+ * overrides repository.
4358
+ *
4359
+ * For callers running outside any tenant context (e.g. tenant-less public
4360
+ * HTTP routes such as the connectors OAuth callback): overrides are
4361
+ * tenant-scoped in storage, so without a tenant there is nothing to fetch —
4362
+ * and asking the repository anyway would require the very context that is
4363
+ * absent.
4364
+ */
4365
+ resolveAllStatic() {
4366
+ return this.resolveNames(this.collectFlagNames(), emptyOverrides(), {});
4367
+ }
4368
+ /** Flag names known to this service: registry entries plus static defaults. */
4369
+ collectFlagNames() {
4365
4370
  const flagNames = /* @__PURE__ */ new Set();
4366
4371
  for (const name of this.registry.listNames()) {
4367
4372
  flagNames.add(name);
@@ -4369,10 +4374,12 @@ var FlagService = class {
4369
4374
  for (const name of this.staticDefaults.keys()) {
4370
4375
  flagNames.add(name);
4371
4376
  }
4372
- const overrides = this.repository && flagNames.size > 0 ? await this.getAllOverrides(context, [...flagNames]) : emptyOverrides();
4377
+ return flagNames;
4378
+ }
4379
+ resolveNames(flagNames, overrides, context) {
4380
+ const resolved = /* @__PURE__ */ new Map();
4373
4381
  for (const name of flagNames) {
4374
- const value = this.resolveValue(name, overrides, context);
4375
- resolved.set(name, value);
4382
+ resolved.set(name, this.resolveValue(name, overrides, context));
4376
4383
  }
4377
4384
  return resolved;
4378
4385
  }
@@ -4760,6 +4767,12 @@ var MEMORY_VIEW = detailView("memory-detail", "Memory").for("memory").default().
4760
4767
  }).tab("content", "Content").richtext("content").titleAttribute("name").build();
4761
4768
  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", "My memories").icon("lock").visibility("private").table().columns("name", "kind", "description", "createdAt").sort("name", "asc").build();
4762
4769
 
4770
+ // src/native/drive.object.ts
4771
+ var DRIVE_OBJECT_NAME = "drives";
4772
+ var DRIVE_OBJECT = object({ name: DRIVE_OBJECT_NAME, label: "Drive" }).sealed().icon("folder").hidden().pluralLabel("Drives").labelExpression("{{ name }}").embeddingExpression("{{ name }}\n{{ description }}").attribute(text({ name: "name", label: "Name" }).required()).attribute(text({ name: "description", label: "Description" }).multiline()).build();
4773
+ var DRIVE_VIEW = detailView("drive-detail", "Drive").for(DRIVE_OBJECT_NAME).default().sidePanel({ attributes: ["description"] }).tab("documents", "Documents").documents().build();
4774
+ var DRIVE_LIST_VIEW = listView("drive-list", "Drives").for(DRIVE_OBJECT_NAME).default().tab("workspace", "Shared").default().icon("users").visibility("workspace").table().columns("name", "description", "updatedAt").sort("name", "asc").tab("mine", "My drives").icon("lock").visibility("private").table().columns("name", "description", "updatedAt").sort("name", "asc").build();
4775
+
4763
4776
  // src/views/registry.ts
4764
4777
  function cloneViewDefinition(view) {
4765
4778
  return structuredClone(view);
@@ -5306,6 +5319,9 @@ var LIVE_EVENT_TYPE_REGISTRY = {
5306
5319
  "notification.count.patch": true,
5307
5320
  "conversation.renamed": true,
5308
5321
  "browser.preview.updated": true,
5322
+ "reflex.state.changed": true,
5323
+ "reflex.run.completed": true,
5324
+ "reflex.authoring.progress": true,
5309
5325
  "channel.revoked": true
5310
5326
  };
5311
5327
  var LIVE_EVENT_TYPES = Object.keys(LIVE_EVENT_TYPE_REGISTRY);
@@ -5409,6 +5425,12 @@ function isLiveEventPayloadForType(type, payload) {
5409
5425
  return isConversationRenamedPayload(payload);
5410
5426
  case "browser.preview.updated":
5411
5427
  return isBrowserPreviewUpdatedPayload(payload);
5428
+ case "reflex.state.changed":
5429
+ return isReflexStateChangedPayload(payload);
5430
+ case "reflex.run.completed":
5431
+ return isReflexRunCompletedPayload(payload);
5432
+ case "reflex.authoring.progress":
5433
+ return isReflexAuthoringProgressPayload(payload);
5412
5434
  case "channel.revoked":
5413
5435
  return isChannelRevokedPayload(payload);
5414
5436
  default:
@@ -5483,7 +5505,9 @@ function isRecordFieldPatch(value) {
5483
5505
  return isRecord2(value) && hasString(value, "fieldKey") && Object.hasOwn(value, "value") && hasVersion(value, "version");
5484
5506
  }
5485
5507
  function isRecordPatchPayload(payload) {
5486
- return payload.type === "record.patch" && hasString(payload, "objectId") && hasString(payload, "recordId") && hasVersion(payload, "recordVersion") && hasOptional(payload, "label", isString) && hasOptional(payload, "metadata", isRecord2) && Array.isArray(payload.fieldPatches) && payload.fieldPatches.every(isRecordFieldPatch) && hasString(payload, "updatedAt");
5508
+ return payload.type === "record.patch" && hasString(payload, "objectId") && hasString(payload, "recordId") && hasVersion(payload, "recordVersion") && hasOptional(payload, "label", isString) && hasOptional(payload, "metadata", isRecord2) && // Strictly `true`: the applier evicts an entity on this bit, so truthy
5509
+ // junk on the wire must not pass as the presence flag (#2637).
5510
+ hasOptional(payload, "fieldsWithheld", (value) => value === true) && Array.isArray(payload.fieldPatches) && payload.fieldPatches.every(isRecordFieldPatch) && hasString(payload, "updatedAt");
5487
5511
  }
5488
5512
  function isRecordDeletedPayload(payload) {
5489
5513
  return payload.type === "record.deleted" && hasString(payload, "objectId") && hasString(payload, "recordId") && hasVersion(payload, "recordVersion") && hasString(payload, "deletedAt");
@@ -5539,6 +5563,27 @@ function isBrowserPreviewUpdatedPayload(payload) {
5539
5563
  const preview = payload.preview;
5540
5564
  return payload.type === "browser.preview.updated" && hasOnlyKeys(payload, BROWSER_PREVIEW_UPDATED_PAYLOAD_KEYS) && isRecord2(preview) && hasOnlyKeys(preview, BROWSER_PREVIEW_DESCRIPTOR_KEYS) && hasNonEmptyString(preview, "previewId") && hasNonEmptyString(preview, "rootSessionId") && hasNonEmptyString(preview, "agentSessionId") && hasNonEmptyString(preview, "browserSession") && isOneOf(preview.status, BROWSER_PREVIEW_STATUSES) && hasVersion(preview, "sequence") && hasIsoDateString(preview, "updatedAt") && preview.previewId === `browser:${preview.agentSessionId}:${preview.browserSession}`;
5541
5565
  }
5566
+ var REFLEX_STATES = ["armed", "disarmed"];
5567
+ var REFLEX_AUTHORING_STATUSES = [
5568
+ "authoring",
5569
+ "compiling",
5570
+ "replaying",
5571
+ "promoted",
5572
+ "failed"
5573
+ ];
5574
+ var REFLEX_SERVED_MODES = [
5575
+ "promoted",
5576
+ "lkg"
5577
+ ];
5578
+ function isReflexStateChangedPayload(payload) {
5579
+ return payload.type === "reflex.state.changed" && hasNonEmptyString(payload, "reflexId") && isOneOf(payload.state, REFLEX_STATES) && hasIsoDateString(payload, "updatedAt");
5580
+ }
5581
+ function isReflexRunCompletedPayload(payload) {
5582
+ return payload.type === "reflex.run.completed" && hasNonEmptyString(payload, "reflexId") && hasNonEmptyString(payload, "runId") && isOneOf(payload.served, REFLEX_SERVED_MODES) && hasVersion(payload, "version") && hasVersion(payload, "wallMs") && hasIsoDateString(payload, "completedAt");
5583
+ }
5584
+ function isReflexAuthoringProgressPayload(payload) {
5585
+ return payload.type === "reflex.authoring.progress" && hasNonEmptyString(payload, "reflexId") && isOneOf(payload.status, REFLEX_AUTHORING_STATUSES) && hasIsoDateString(payload, "updatedAt");
5586
+ }
5542
5587
  function isChannelRevokedPayload(payload) {
5543
5588
  return payload.type === "channel.revoked" && hasString(payload, "channel") && isOneOf(payload.reason, CHANNEL_REVOKED_REASONS);
5544
5589
  }
@@ -6328,7 +6373,11 @@ function evaluateCallNode(functionName, args, input) {
6328
6373
  assertComputedFunctionName(functionName);
6329
6374
  validateArity(functionName, args.length);
6330
6375
  if (functionName === "if") {
6331
- return evaluateAst(args[0], input) ? evaluateAst(args[1], input) : evaluateAst(args[2], input);
6376
+ const condition = evaluateAst(args[0], input);
6377
+ if (condition === null) {
6378
+ return null;
6379
+ }
6380
+ return condition ? evaluateAst(args[1], input) : evaluateAst(args[2], input);
6332
6381
  }
6333
6382
  return evaluateCall(
6334
6383
  functionName,
@@ -6374,8 +6423,10 @@ function evaluateBinary(operator, left, right) {
6374
6423
  return compareWith(left, right, (result) => result <= 0);
6375
6424
  case "==":
6376
6425
  return equalScalar(left, right);
6377
- case "!=":
6378
- return !equalScalar(left, right);
6426
+ case "!=": {
6427
+ const equal = equalScalar(left, right);
6428
+ return equal === null ? null : !equal;
6429
+ }
6379
6430
  default:
6380
6431
  return unreachable(operator);
6381
6432
  }
@@ -6391,6 +6442,9 @@ function compareWith(left, right, predicate) {
6391
6442
  return result === null ? null : predicate(result);
6392
6443
  }
6393
6444
  function compare(left, right) {
6445
+ if (!areCommensurable([left, right])) {
6446
+ return null;
6447
+ }
6394
6448
  const leftNumber = toFiniteNumber(left);
6395
6449
  const rightNumber = toFiniteNumber(right);
6396
6450
  if (leftNumber !== null && rightNumber !== null) {
@@ -6407,6 +6461,9 @@ function equalScalar(left, right) {
6407
6461
  if (left === null || left === void 0 || right === null || right === void 0) {
6408
6462
  return false;
6409
6463
  }
6464
+ if (!areCommensurable([left, right])) {
6465
+ return null;
6466
+ }
6410
6467
  return compare(left, right) === 0;
6411
6468
  }
6412
6469
  function assertComputedFunctionName(name) {
@@ -6427,8 +6484,14 @@ function evaluateCall(functionName, args) {
6427
6484
  case "concat":
6428
6485
  return args.filter((arg) => arg !== null && arg !== void 0).map(String).join("");
6429
6486
  case "sum":
6487
+ if (!areCommensurable(args)) {
6488
+ return null;
6489
+ }
6430
6490
  return numericValues(args).reduce((total, value) => total + value, 0);
6431
6491
  case "avg": {
6492
+ if (!areCommensurable(args)) {
6493
+ return null;
6494
+ }
6432
6495
  const values = numericValues(args);
6433
6496
  return values.length > 0 ? values.reduce((total, value) => total + value, 0) / values.length : null;
6434
6497
  }
@@ -6466,7 +6529,22 @@ function unreachable(value) {
6466
6529
  function numericValues(values) {
6467
6530
  return flatten(values).map(toFiniteNumber).filter((value) => value !== null);
6468
6531
  }
6532
+ function areCommensurable(values) {
6533
+ const codes = /* @__PURE__ */ new Set();
6534
+ for (const value of flatten(values)) {
6535
+ if (isCurrencyValue(value)) {
6536
+ codes.add(currencyCode(value));
6537
+ }
6538
+ }
6539
+ return codes.size <= 1;
6540
+ }
6541
+ function currencyCode(value) {
6542
+ return value.code.toUpperCase();
6543
+ }
6469
6544
  function numericBinary(left, right, operation) {
6545
+ if (!areCommensurable([left, right])) {
6546
+ return null;
6547
+ }
6470
6548
  const leftNumber = toFiniteNumber(left);
6471
6549
  const rightNumber = toFiniteNumber(right);
6472
6550
  if (leftNumber === null || rightNumber === null) {
@@ -6476,6 +6554,9 @@ function numericBinary(left, right, operation) {
6476
6554
  return Number.isFinite(result) ? result : null;
6477
6555
  }
6478
6556
  function minMax(values, mode) {
6557
+ if (!areCommensurable(values)) {
6558
+ return null;
6559
+ }
6479
6560
  const numbers = numericValues(values);
6480
6561
  if (numbers.length > 0) {
6481
6562
  return mode === "min" ? Math.min(...numbers) : Math.max(...numbers);
@@ -6554,6 +6635,9 @@ function toDate(value) {
6554
6635
  return Number.isNaN(date2.getTime()) ? null : date2;
6555
6636
  }
6556
6637
  function uniqueKey(value) {
6638
+ if (isCurrencyValue(value)) {
6639
+ return `currency:${currencyCode(value)}:${value.value}`;
6640
+ }
6557
6641
  const numberValue = toFiniteNumber(value);
6558
6642
  if (numberValue !== null) {
6559
6643
  return `number:${numberValue}`;
@@ -7506,4 +7590,995 @@ var persistedSchemaPlanSchema = z.preprocess(
7506
7590
  structuralPersistedSchemaPlanSchema
7507
7591
  );
7508
7592
 
7509
- export { AGENT_UI_BATCH_MAX_BYTES, AGENT_UI_BATCH_MAX_ITEMS, 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, 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, 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, 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, USER_WORK_POSTURES, accessLevelToActions, actionsToAccessLevel, agent, agentDisplayName, applyPipes, applyRelationProps, assertAcyclicComputedDependencies, booleanFlag, buildAgentFallbackTitle, buildPermissionFlags, buildPropertySchema, buildQualifiedAttribute, checkbox, compileComputedFormula, compileRollupAttribute, computeByteMagnitude, conversationDisplayTitle, createFlagRegistry, createFlagService, createStandardSchemaProps, currency, date, dateInTimezone, dateValueStart, deriveInitials, destructiveSchema, detailView, document, evaluateComputedAst, evaluateComputedFormula, evaluateComputedFormulaWithResult, evaluateFilterState, evaluateRecordFilterState, extractAttributeNames, extractValueRefs, flagRegistry, form, formRegistry, formatAttributeValue, formatByteSize, formatComputedResult, formatLocationValue, formula, generateDefaultDetailView, generateDefaultListView, getActiveTab, getErrorMessage, getLiveProtocolPayloadChannel, getRecordCreatorPrincipalId, getSlotFieldTargets, getUserDisplayName, group, hasDestructiveEntries, hasOptions, includesAction, inferInverseCardinality, inferRollupReturnType, isAgentUIMessageBatch, isAttributeSortable2 as isAttributeSortable, isBilateralRelation, isCheckboxEquality, isComputedFunctionName, isDateRangeValue, isDefaultRole, isDetailView, isDocumentAttribute, isEmptyObject, isFieldGroup, isFormDefinition, isFormFieldsRow, isFormFreeFieldRef, isFormHeadingRow, isFormSeparatorRow, isFormSlotFieldRef, isFormTextRow, isLabelExpression, isListView, isLiveEventEnvelope, isLiveEventPayload, isLiveEventPayloadForType, isLiveEventType, isNotEmpty, isPlainRecord2 as isPlainRecord, isRelationGroup, isStandardSchema, isTerminalSessionStatus, isTerminalState, isUniversalRelation, jsonFlag, legacyStatusToSessionState, listView, liveChannelKey, location, matchesAccepts, multiselect, nativeAgentUIPartIdMetadataKey, normalizeDateValue, number, numberFlag, object, parseCountMode, parseLiveChannelKey, parseNativeAgentUIPartIdsMetadata, parseOptionalCountMode, parseQualifiedAttribute, persistedDefaultViewTargetSchema, persistedSchemaPlanSchema, phone, plannedAttributeSchema, plannedInlineAttributeSchema, plannedObjectSchema, proposedDefaultViewTargetSchema, registry, relation, relationGroup, relationPropertyDefs, renderLabelExpression, resetViewToDefault, resolveAttributeDefaultValue, resolveFieldRequired, resolvePropertyDefinitions, richtext, rollup, rollupToFormulaExpression, schemaPlanSchema, select, sessionStateToLegacyStatus, status, stringFlag, text, toUndefinedIfEmpty, user, validateAttributeName, validateLabelExpression, validateObjectName, validateViewName, viewRegistry, viewStateKey, viewSyncPayload };
7593
+ // src/architect/define-operation.ts
7594
+ function defineOperation(def) {
7595
+ return def;
7596
+ }
7597
+ var operationBase = { id: z.string().min(1) };
7598
+ var viewOperationBase = { ...operationBase, viewId: z.string().min(1) };
7599
+ function mapView(state, viewId, fn) {
7600
+ if (!state.views.some((v) => v.id === viewId)) {
7601
+ throw new ValidationError(`View "${viewId}" is not in the draftable state`, []);
7602
+ }
7603
+ return { ...state, views: state.views.map((v) => v.id === viewId ? fn(v) : v) };
7604
+ }
7605
+ function moveWithin(items, from, toIndex) {
7606
+ const next = [...items];
7607
+ const [item] = next.splice(from, 1);
7608
+ next.splice(toIndex, 0, item);
7609
+ return next;
7610
+ }
7611
+ function reorderById(items, order, what) {
7612
+ if (order.length !== items.length) {
7613
+ throw new ValidationError(
7614
+ `${what} order lists ${order.length} ids for ${items.length} items`,
7615
+ []
7616
+ );
7617
+ }
7618
+ return order.map((id) => {
7619
+ const found = items.find((item) => item.id === id);
7620
+ if (!found) throw new ValidationError(`${what} "${id}" is not in this collection`, []);
7621
+ return found;
7622
+ });
7623
+ }
7624
+
7625
+ // src/architect/operations/detail-view.ts
7626
+ function mapFormTab(view, tabId, fn) {
7627
+ const found = view.tabs.find((t) => t.id === tabId);
7628
+ if (!found) throw new ValidationError(`Tab "${tabId}" is not in view "${view.id}"`, []);
7629
+ if (found.type !== "form") {
7630
+ throw new ValidationError(`Tab "${tabId}" is not a form tab`, []);
7631
+ }
7632
+ return { ...view, tabs: view.tabs.map((t) => t.id === tabId ? fn(found) : t) };
7633
+ }
7634
+ function requireGroup(tab, groupId) {
7635
+ const found = tab.groups.find((g) => g.id === groupId);
7636
+ if (!found) throw new ValidationError(`Group "${groupId}" is not in tab "${tab.id}"`, []);
7637
+ return found;
7638
+ }
7639
+ function locateField(tab, fieldId) {
7640
+ for (const group2 of tab.groups) {
7641
+ const field = group2.fields.find((f) => f.id === fieldId);
7642
+ if (field) return { group: group2, field };
7643
+ }
7644
+ throw new ValidationError(`Field slot "${fieldId}" is not in tab "${tab.id}"`, []);
7645
+ }
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
+ );
7658
+ var addTabSchema = z.object({
7659
+ ...viewOperationBase,
7660
+ type: z.literal("add_tab"),
7661
+ tab: tabPayload
7662
+ });
7663
+ var addTab = defineOperation({
7664
+ type: "add_tab",
7665
+ schema: addTabSchema,
7666
+ apply: (state, op) => mapView(state, op.viewId, (view) => {
7667
+ if (view.tabs.some((t) => t.id === op.tab.id)) {
7668
+ throw new ValidationError(`Tab "${op.tab.id}" already exists in view "${op.viewId}"`, []);
7669
+ }
7670
+ return { ...view, tabs: [...view.tabs, op.tab] };
7671
+ }),
7672
+ focus: (op) => ({ viewId: op.viewId, tabId: op.tab.id }),
7673
+ describe: (op) => `Ajoute l'onglet \xAB ${op.tab.label} \xBB`
7674
+ });
7675
+ var removeTabSchema = z.object({
7676
+ ...viewOperationBase,
7677
+ type: z.literal("remove_tab"),
7678
+ tabId: z.string().min(1)
7679
+ });
7680
+ var removeTab = defineOperation({
7681
+ type: "remove_tab",
7682
+ schema: removeTabSchema,
7683
+ apply: (state, op) => mapView(state, op.viewId, (view) => {
7684
+ if (!view.tabs.some((t) => t.id === op.tabId)) {
7685
+ throw new ValidationError(`Tab "${op.tabId}" is not in view "${op.viewId}"`, []);
7686
+ }
7687
+ return { ...view, tabs: view.tabs.filter((t) => t.id !== op.tabId) };
7688
+ }),
7689
+ focus: (op) => ({ viewId: op.viewId }),
7690
+ describe: (op) => `Supprime l'onglet ${op.tabId}`
7691
+ });
7692
+ var updateTabSchema = z.object({
7693
+ ...viewOperationBase,
7694
+ type: z.literal("update_tab"),
7695
+ 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")
7701
+ });
7702
+ var updateTab = defineOperation({
7703
+ type: "update_tab",
7704
+ schema: updateTabSchema,
7705
+ apply: (state, op) => mapView(state, op.viewId, (view) => {
7706
+ if (!view.tabs.some((t) => t.id === op.tabId)) {
7707
+ throw new ValidationError(`Tab "${op.tabId}" is not in view "${op.viewId}"`, []);
7708
+ }
7709
+ return {
7710
+ ...view,
7711
+ tabs: view.tabs.map((t) => t.id === op.tabId ? { ...t, ...op.changes } : t)
7712
+ };
7713
+ }),
7714
+ focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
7715
+ describe: (op) => op.changes.label ? `Renomme l'onglet en \xAB ${op.changes.label} \xBB` : `Modifie l'onglet ${op.tabId}`
7716
+ });
7717
+ var reorderTabsSchema = z.object({
7718
+ ...viewOperationBase,
7719
+ type: z.literal("reorder_tabs"),
7720
+ tabOrder: z.array(z.string().min(1))
7721
+ });
7722
+ var reorderTabs = defineOperation({
7723
+ type: "reorder_tabs",
7724
+ schema: reorderTabsSchema,
7725
+ apply: (state, op) => mapView(state, op.viewId, (view) => ({
7726
+ ...view,
7727
+ tabs: reorderById(view.tabs, op.tabOrder, "Tab")
7728
+ })),
7729
+ focus: (op) => ({ viewId: op.viewId }),
7730
+ describe: () => "R\xE9ordonne les onglets"
7731
+ });
7732
+ var addGroupSchema = z.object({
7733
+ ...viewOperationBase,
7734
+ type: z.literal("add_group"),
7735
+ tabId: z.string().min(1),
7736
+ group: groupPayload
7737
+ });
7738
+ var addGroup = defineOperation({
7739
+ type: "add_group",
7740
+ schema: addGroupSchema,
7741
+ apply: (state, op) => mapView(
7742
+ state,
7743
+ op.viewId,
7744
+ (view) => mapFormTab(view, op.tabId, (tab) => {
7745
+ if (tab.groups.some((g) => g.id === op.group.id)) {
7746
+ throw new ValidationError(
7747
+ `Group "${op.group.id}" already exists in tab "${op.tabId}"`,
7748
+ []
7749
+ );
7750
+ }
7751
+ return { ...tab, groups: [...tab.groups, op.group] };
7752
+ })
7753
+ ),
7754
+ focus: (op) => ({ viewId: op.viewId, tabId: op.tabId, groupId: op.group.id }),
7755
+ describe: (op) => `Ajoute le groupe \xAB ${op.group.label} \xBB`
7756
+ });
7757
+ var removeGroupSchema = z.object({
7758
+ ...viewOperationBase,
7759
+ type: z.literal("remove_group"),
7760
+ tabId: z.string().min(1),
7761
+ groupId: z.string().min(1)
7762
+ });
7763
+ var removeGroup = defineOperation({
7764
+ type: "remove_group",
7765
+ schema: removeGroupSchema,
7766
+ apply: (state, op) => mapView(
7767
+ state,
7768
+ op.viewId,
7769
+ (view) => mapFormTab(view, op.tabId, (tab) => {
7770
+ requireGroup(tab, op.groupId);
7771
+ return { ...tab, groups: tab.groups.filter((g) => g.id !== op.groupId) };
7772
+ })
7773
+ ),
7774
+ focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
7775
+ describe: (op) => `Supprime le groupe ${op.groupId}`
7776
+ });
7777
+ var updateGroupSchema = z.object({
7778
+ ...viewOperationBase,
7779
+ type: z.literal("update_group"),
7780
+ tabId: z.string().min(1),
7781
+ groupId: z.string().min(1),
7782
+ changes: z.object({
7783
+ label: z.string().min(1).optional(),
7784
+ description: z.string().optional(),
7785
+ collapsible: z.boolean().optional(),
7786
+ collapsed: z.boolean().optional(),
7787
+ order: z.number().int().optional()
7788
+ }).refine((c) => Object.keys(c).length > 0, "update_group needs at least one change")
7789
+ });
7790
+ var updateGroup = defineOperation({
7791
+ type: "update_group",
7792
+ schema: updateGroupSchema,
7793
+ apply: (state, op) => mapView(
7794
+ state,
7795
+ op.viewId,
7796
+ (view) => mapFormTab(view, op.tabId, (tab) => {
7797
+ requireGroup(tab, op.groupId);
7798
+ return {
7799
+ ...tab,
7800
+ groups: tab.groups.map((g) => g.id === op.groupId ? { ...g, ...op.changes } : g)
7801
+ };
7802
+ })
7803
+ ),
7804
+ focus: (op) => ({ viewId: op.viewId, tabId: op.tabId, groupId: op.groupId }),
7805
+ describe: (op) => op.changes.label ? `Renomme le groupe en \xAB ${op.changes.label} \xBB` : "Modifie le groupe"
7806
+ });
7807
+ var reorderGroupsSchema = z.object({
7808
+ ...viewOperationBase,
7809
+ type: z.literal("reorder_groups"),
7810
+ tabId: z.string().min(1),
7811
+ groupOrder: z.array(z.string().min(1))
7812
+ });
7813
+ var reorderGroups = defineOperation({
7814
+ type: "reorder_groups",
7815
+ schema: reorderGroupsSchema,
7816
+ apply: (state, op) => mapView(
7817
+ state,
7818
+ op.viewId,
7819
+ (view) => mapFormTab(view, op.tabId, (tab) => ({
7820
+ ...tab,
7821
+ groups: reorderById(tab.groups, op.groupOrder, "Group")
7822
+ }))
7823
+ ),
7824
+ focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
7825
+ describe: () => "R\xE9ordonne les groupes"
7826
+ });
7827
+ var addFieldSchema = z.object({
7828
+ ...viewOperationBase,
7829
+ type: z.literal("add_field"),
7830
+ tabId: z.string().min(1),
7831
+ groupId: z.string().min(1),
7832
+ field: fieldPayload,
7833
+ index: z.number().int().min(0).optional()
7834
+ });
7835
+ var addField = defineOperation({
7836
+ type: "add_field",
7837
+ schema: addFieldSchema,
7838
+ apply: (state, op) => mapView(
7839
+ state,
7840
+ op.viewId,
7841
+ (view) => mapFormTab(view, op.tabId, (tab) => {
7842
+ requireGroup(tab, op.groupId);
7843
+ if (tab.groups.some((g) => g.fields.some((f) => f.id === op.field.id))) {
7844
+ throw new ValidationError(
7845
+ `Field slot "${op.field.id}" already exists in tab "${op.tabId}"`,
7846
+ []
7847
+ );
7848
+ }
7849
+ return {
7850
+ ...tab,
7851
+ groups: tab.groups.map((group2) => {
7852
+ if (group2.id !== op.groupId) return group2;
7853
+ const at = op.index ?? group2.fields.length;
7854
+ return {
7855
+ ...group2,
7856
+ fields: [...group2.fields.slice(0, at), op.field, ...group2.fields.slice(at)]
7857
+ };
7858
+ })
7859
+ };
7860
+ })
7861
+ ),
7862
+ focus: (op) => ({
7863
+ viewId: op.viewId,
7864
+ tabId: op.tabId,
7865
+ groupId: op.groupId,
7866
+ fieldId: op.field.id
7867
+ }),
7868
+ describe: (op) => `Ajoute le champ ${op.field.attribute ?? op.field.id}`
7869
+ });
7870
+ var removeFieldSchema = z.object({
7871
+ ...viewOperationBase,
7872
+ type: z.literal("remove_field"),
7873
+ tabId: z.string().min(1),
7874
+ fieldId: z.string().min(1)
7875
+ });
7876
+ var removeField = defineOperation({
7877
+ type: "remove_field",
7878
+ schema: removeFieldSchema,
7879
+ apply: (state, op) => mapView(
7880
+ state,
7881
+ op.viewId,
7882
+ (view) => mapFormTab(view, op.tabId, (tab) => {
7883
+ const { group: group2 } = locateField(tab, op.fieldId);
7884
+ return {
7885
+ ...tab,
7886
+ groups: tab.groups.map(
7887
+ (g) => g.id === group2.id ? { ...g, fields: g.fields.filter((f) => f.id !== op.fieldId) } : g
7888
+ )
7889
+ };
7890
+ })
7891
+ ),
7892
+ focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
7893
+ describe: (op) => `Retire le champ ${op.fieldId}`
7894
+ });
7895
+ var moveFieldSchema = z.object({
7896
+ ...viewOperationBase,
7897
+ type: z.literal("move_field"),
7898
+ tabId: z.string().min(1),
7899
+ fieldId: z.string().min(1),
7900
+ toGroupId: z.string().min(1),
7901
+ toIndex: z.number().int().min(0)
7902
+ });
7903
+ var moveField = defineOperation({
7904
+ type: "move_field",
7905
+ schema: moveFieldSchema,
7906
+ apply: (state, op) => mapView(
7907
+ state,
7908
+ op.viewId,
7909
+ (view) => mapFormTab(view, op.tabId, (tab) => {
7910
+ const { group: source, field } = locateField(tab, op.fieldId);
7911
+ const target = requireGroup(tab, op.toGroupId);
7912
+ if (source.id === target.id) {
7913
+ const from = source.fields.findIndex((f) => f.id === op.fieldId);
7914
+ return {
7915
+ ...tab,
7916
+ groups: tab.groups.map(
7917
+ (g) => g.id === source.id ? { ...g, fields: moveWithin(g.fields, from, op.toIndex) } : g
7918
+ )
7919
+ };
7920
+ }
7921
+ return {
7922
+ ...tab,
7923
+ groups: tab.groups.map((group2) => {
7924
+ if (group2.id === source.id) {
7925
+ return { ...group2, fields: group2.fields.filter((f) => f.id !== op.fieldId) };
7926
+ }
7927
+ if (group2.id === target.id) {
7928
+ return {
7929
+ ...group2,
7930
+ fields: [
7931
+ ...group2.fields.slice(0, op.toIndex),
7932
+ field,
7933
+ ...group2.fields.slice(op.toIndex)
7934
+ ]
7935
+ };
7936
+ }
7937
+ return group2;
7938
+ })
7939
+ };
7940
+ })
7941
+ ),
7942
+ focus: (op) => ({
7943
+ viewId: op.viewId,
7944
+ tabId: op.tabId,
7945
+ groupId: op.toGroupId,
7946
+ fieldId: op.fieldId
7947
+ }),
7948
+ describe: (op) => `D\xE9place le champ ${op.fieldId} vers le groupe ${op.toGroupId}`
7949
+ });
7950
+ var updateFieldSchema = z.object({
7951
+ ...viewOperationBase,
7952
+ type: z.literal("update_field"),
7953
+ tabId: z.string().min(1),
7954
+ fieldId: z.string().min(1),
7955
+ changes: z.object({
7956
+ label: z.string().optional(),
7957
+ readOnly: z.boolean().optional(),
7958
+ span: z.number().int().min(1).max(12).optional()
7959
+ }).refine((c) => Object.keys(c).length > 0, "update_field needs at least one change")
7960
+ });
7961
+ var updateField = defineOperation({
7962
+ type: "update_field",
7963
+ schema: updateFieldSchema,
7964
+ apply: (state, op) => mapView(
7965
+ state,
7966
+ op.viewId,
7967
+ (view) => mapFormTab(view, op.tabId, (tab) => {
7968
+ locateField(tab, op.fieldId);
7969
+ return {
7970
+ ...tab,
7971
+ groups: tab.groups.map((group2) => ({
7972
+ ...group2,
7973
+ fields: group2.fields.map(
7974
+ (f) => f.id === op.fieldId ? { ...f, ...op.changes } : f
7975
+ )
7976
+ }))
7977
+ };
7978
+ })
7979
+ ),
7980
+ focus: (op) => ({ viewId: op.viewId, tabId: op.tabId, fieldId: op.fieldId }),
7981
+ describe: (op) => `Modifie le champ ${op.fieldId}`
7982
+ });
7983
+ var updateTableTabSchema = z.object({
7984
+ ...viewOperationBase,
7985
+ type: z.literal("update_table_tab"),
7986
+ 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")
7996
+ });
7997
+ var updateTableTab = defineOperation({
7998
+ type: "update_table_tab",
7999
+ schema: updateTableTabSchema,
8000
+ apply: (state, op) => mapView(state, op.viewId, (view) => {
8001
+ const found = view.tabs.find((t) => t.id === op.tabId);
8002
+ if (!found) throw new ValidationError(`Tab "${op.tabId}" is not in view "${view.id}"`, []);
8003
+ if (found.type !== "table") {
8004
+ throw new ValidationError(`Tab "${op.tabId}" is not a table tab`, []);
8005
+ }
8006
+ return {
8007
+ ...view,
8008
+ tabs: view.tabs.map((t) => t.id === op.tabId ? { ...t, ...op.changes } : t)
8009
+ };
8010
+ }),
8011
+ focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
8012
+ describe: (op) => op.changes.columns ? `Affiche ${op.changes.columns.length} colonne(s) dans l'onglet ${op.tabId}` : `Modifie l'onglet ${op.tabId}`
8013
+ });
8014
+ var setSidePanelSchema = z.object({
8015
+ ...viewOperationBase,
8016
+ type: z.literal("set_side_panel"),
8017
+ sidePanel: z.object({ attributes: z.array(z.string().min(1)), width: z.number().int().min(1).optional() }).nullable()
8018
+ });
8019
+ var setSidePanel = defineOperation({
8020
+ type: "set_side_panel",
8021
+ schema: setSidePanelSchema,
8022
+ apply: (state, op) => mapView(state, op.viewId, (view) => ({
8023
+ ...view,
8024
+ config: {
8025
+ ...view.config,
8026
+ sidePanel: op.sidePanel ?? void 0
8027
+ }
8028
+ })),
8029
+ focus: (op) => ({ viewId: op.viewId }),
8030
+ describe: (op) => op.sidePanel ? "Active le panneau lat\xE9ral" : "Retire le panneau lat\xE9ral"
8031
+ });
8032
+ var DETAIL_VIEW_OPERATIONS = [
8033
+ addTab,
8034
+ removeTab,
8035
+ updateTab,
8036
+ reorderTabs,
8037
+ addGroup,
8038
+ removeGroup,
8039
+ updateGroup,
8040
+ reorderGroups,
8041
+ addField,
8042
+ removeField,
8043
+ moveField,
8044
+ updateField,
8045
+ updateTableTab,
8046
+ setSidePanel
8047
+ ];
8048
+ var listTabBase = { ...viewOperationBase, tabId: z.string().min(1) };
8049
+ function mapListTab(state, viewId, tabId, fn) {
8050
+ return mapView(state, viewId, (view) => {
8051
+ const tabs = view.config.tabs ?? [];
8052
+ if (!tabs.some((t) => t.id === tabId)) {
8053
+ throw new ValidationError(`List tab "${tabId}" is not in view "${viewId}"`, []);
8054
+ }
8055
+ return {
8056
+ ...view,
8057
+ config: { ...view.config, tabs: tabs.map((t) => t.id === tabId ? fn(t) : t) }
8058
+ };
8059
+ });
8060
+ }
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));
8069
+ function setOnTab(type, key, valueSchema, describe) {
8070
+ const schema = z.object({ ...listTabBase, type: z.literal(type), value: valueSchema });
8071
+ return defineOperation({
8072
+ type,
8073
+ schema,
8074
+ apply: (state, op) => mapListTab(state, op.viewId, op.tabId, (tab) => {
8075
+ if (op.value === null) {
8076
+ const { [key]: _dropped, ...rest } = tab;
8077
+ return rest;
8078
+ }
8079
+ return { ...tab, [key]: op.value };
8080
+ }),
8081
+ focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
8082
+ describe: (op) => describe(op.value)
8083
+ });
8084
+ }
8085
+ var addListTabSchema = z.object({
8086
+ ...viewOperationBase,
8087
+ type: z.literal("add_list_tab"),
8088
+ tab: listTabPayload
8089
+ });
8090
+ var addListTab = defineOperation({
8091
+ type: "add_list_tab",
8092
+ schema: addListTabSchema,
8093
+ apply: (state, op) => mapView(state, op.viewId, (view) => {
8094
+ const tabs = view.config.tabs ?? [];
8095
+ if (tabs.some((t) => t.id === op.tab.id)) {
8096
+ throw new ValidationError(
8097
+ `List tab "${op.tab.id}" already exists in view "${op.viewId}"`,
8098
+ []
8099
+ );
8100
+ }
8101
+ return { ...view, config: { ...view.config, tabs: [...tabs, op.tab] } };
8102
+ }),
8103
+ focus: (op) => ({ viewId: op.viewId, tabId: op.tab.id }),
8104
+ describe: (op) => `Ajoute l'onglet \xAB ${op.tab.label} \xBB`
8105
+ });
8106
+ var removeListTabSchema = z.object({
8107
+ ...listTabBase,
8108
+ type: z.literal("remove_list_tab")
8109
+ });
8110
+ var removeListTab = defineOperation({
8111
+ type: "remove_list_tab",
8112
+ schema: removeListTabSchema,
8113
+ apply: (state, op) => mapView(state, op.viewId, (view) => {
8114
+ const tabs = view.config.tabs ?? [];
8115
+ if (!tabs.some((t) => t.id === op.tabId)) {
8116
+ throw new ValidationError(`List tab "${op.tabId}" is not in view "${op.viewId}"`, []);
8117
+ }
8118
+ return {
8119
+ ...view,
8120
+ config: { ...view.config, tabs: tabs.filter((t) => t.id !== op.tabId) }
8121
+ };
8122
+ }),
8123
+ focus: (op) => ({ viewId: op.viewId }),
8124
+ describe: (op) => `Supprime l'onglet ${op.tabId}`
8125
+ });
8126
+ var updateListTabSchema = z.object({
8127
+ ...listTabBase,
8128
+ type: z.literal("update_list_tab"),
8129
+ changes: z.object({
8130
+ label: z.string().min(1).optional(),
8131
+ icon: z.custom((v) => typeof v === "string" && v.length > 0).optional(),
8132
+ default: z.boolean().optional(),
8133
+ visibility: z.enum(LIST_VIEW_TAB_VISIBILITIES).optional()
8134
+ }).refine((c) => Object.keys(c).length > 0, "update_list_tab needs at least one change")
8135
+ });
8136
+ var updateListTab = defineOperation({
8137
+ type: "update_list_tab",
8138
+ schema: updateListTabSchema,
8139
+ apply: (state, op) => mapListTab(state, op.viewId, op.tabId, (tab) => ({ ...tab, ...op.changes })),
8140
+ focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
8141
+ describe: (op) => op.changes.label ? `Renomme l'onglet en \xAB ${op.changes.label} \xBB` : `Modifie l'onglet ${op.tabId}`
8142
+ });
8143
+ var reorderListTabsSchema = z.object({
8144
+ ...viewOperationBase,
8145
+ type: z.literal("reorder_list_tabs"),
8146
+ tabOrder: z.array(z.string().min(1))
8147
+ });
8148
+ var reorderListTabs = defineOperation({
8149
+ type: "reorder_list_tabs",
8150
+ schema: reorderListTabsSchema,
8151
+ apply: (state, op) => mapView(state, op.viewId, (view) => ({
8152
+ ...view,
8153
+ config: {
8154
+ ...view.config,
8155
+ tabs: reorderById(view.config.tabs ?? [], op.tabOrder, "List tab")
8156
+ }
8157
+ })),
8158
+ focus: (op) => ({ viewId: op.viewId }),
8159
+ describe: () => "R\xE9ordonne les onglets"
8160
+ });
8161
+ var setColumns = setOnTab(
8162
+ "set_columns",
8163
+ "columns",
8164
+ z.array(z.string().min(1)),
8165
+ // Defensive on shape: a summary is rendered in a list beside other summaries,
8166
+ // and one malformed payload must not take the page down with it.
8167
+ (value) => `Affiche ${Array.isArray(value) ? value.length : 0} colonne(s)`
8168
+ );
8169
+ var setColumnSizing = setOnTab(
8170
+ "set_column_sizing",
8171
+ "columnSizing",
8172
+ z.record(z.string(), z.number().int().positive()),
8173
+ () => "Ajuste la largeur des colonnes"
8174
+ );
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
+ );
8187
+ var setFilters = setOnTab(
8188
+ "set_filters",
8189
+ "filters",
8190
+ filterGroupPayload.nullable(),
8191
+ (value) => value ? "Modifie les filtres" : "Retire les filtres"
8192
+ );
8193
+ var setSorts = setOnTab(
8194
+ "set_sorts",
8195
+ "sorts",
8196
+ sortRulesPayload.nullable(),
8197
+ (value) => value ? "Modifie le tri" : "Retire le tri"
8198
+ );
8199
+ var setCreateMode = setOnTab(
8200
+ "set_create_mode",
8201
+ "createMode",
8202
+ z.enum(["redirect", "inline", "peek"]),
8203
+ (value) => `Cr\xE9ation en mode ${value}`
8204
+ );
8205
+ var setReadOnly = setOnTab(
8206
+ "set_read_only",
8207
+ "readOnly",
8208
+ z.boolean(),
8209
+ (value) => value ? "Passe l'onglet en lecture seule" : "Rend l'onglet modifiable"
8210
+ );
8211
+ var setCardUserAttribute = setOnTab(
8212
+ "set_card_user_attribute",
8213
+ "cardUserAttribute",
8214
+ z.string().min(1).nullable(),
8215
+ (value) => value ? `Affiche ${value} sur les cartes` : "Retire l'utilisateur des cartes"
8216
+ );
8217
+ var setCardDateAttribute = setOnTab(
8218
+ "set_card_date_attribute",
8219
+ "cardDateAttribute",
8220
+ z.string().min(1).nullable(),
8221
+ (value) => value ? `Affiche ${value} sur les cartes` : "Retire la date des cartes"
8222
+ );
8223
+ var setDefaultFiltersSchema = z.object({
8224
+ ...viewOperationBase,
8225
+ type: z.literal("set_default_filters"),
8226
+ filters: filterGroupPayload.nullable()
8227
+ });
8228
+ var setDefaultFilters = defineOperation({
8229
+ type: "set_default_filters",
8230
+ schema: setDefaultFiltersSchema,
8231
+ apply: (state, op) => mapView(state, op.viewId, (view) => {
8232
+ if (op.filters === null) {
8233
+ const { defaultFilters: _dropped, ...rest } = view.config;
8234
+ return { ...view, config: rest };
8235
+ }
8236
+ return { ...view, config: { ...view.config, defaultFilters: op.filters } };
8237
+ }),
8238
+ focus: (op) => ({ viewId: op.viewId }),
8239
+ describe: (op) => op.filters ? "Modifie les filtres de la vue" : "Retire les filtres de la vue"
8240
+ });
8241
+ var LIST_VIEW_OPERATIONS = [
8242
+ setDefaultFilters,
8243
+ addListTab,
8244
+ removeListTab,
8245
+ updateListTab,
8246
+ reorderListTabs,
8247
+ setColumns,
8248
+ setColumnSizing,
8249
+ setLayout,
8250
+ setGroupBy,
8251
+ setFilters,
8252
+ setSorts,
8253
+ setCreateMode,
8254
+ setReadOnly,
8255
+ setCardUserAttribute,
8256
+ setCardDateAttribute
8257
+ ];
8258
+ function requireObject(state, objectId) {
8259
+ if (!state.objects.some((o) => o.id === objectId)) {
8260
+ throw new ValidationError(`Object "${objectId}" is not in the draftable state`, []);
8261
+ }
8262
+ }
8263
+ var objectOperationBase = { ...operationBase, objectId: z.string().min(1) };
8264
+ var addObjectSchema = z.object({
8265
+ ...objectOperationBase,
8266
+ type: z.literal("add_object"),
8267
+ name: z.string().min(1),
8268
+ label: z.string().min(1),
8269
+ icon: z.string().min(1).optional()
8270
+ });
8271
+ var addObject = defineOperation({
8272
+ type: "add_object",
8273
+ schema: addObjectSchema,
8274
+ apply: (state, op) => {
8275
+ if (state.objects.some((o) => o.name === op.name)) {
8276
+ throw new ValidationError(`Object "${op.name}" already exists`, []);
8277
+ }
8278
+ if (state.objects.some((o) => o.id === op.objectId)) {
8279
+ throw new ValidationError(`Object id "${op.objectId}" is already taken`, []);
8280
+ }
8281
+ const created = {
8282
+ id: op.objectId,
8283
+ name: op.name,
8284
+ label: op.label,
8285
+ ...op.icon === void 0 ? {} : { icon: op.icon }
8286
+ };
8287
+ return { ...state, objects: [...state.objects, created] };
8288
+ },
8289
+ // The caller generates objectId, so a draft object is addressable by route
8290
+ // before it exists — that is what lets the app navigate to it live.
8291
+ focus: (op) => ({ objectId: op.objectId }),
8292
+ describe: (op) => `Cr\xE9e l'objet \xAB ${op.label} \xBB`
8293
+ });
8294
+ var updateObjectSchema = z.object({
8295
+ ...objectOperationBase,
8296
+ type: z.literal("update_object"),
8297
+ 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
+ });
8299
+ var updateObject = defineOperation({
8300
+ type: "update_object",
8301
+ schema: updateObjectSchema,
8302
+ apply: (state, op) => {
8303
+ requireObject(state, op.objectId);
8304
+ return {
8305
+ ...state,
8306
+ objects: state.objects.map((o) => o.id === op.objectId ? { ...o, ...op.changes } : o)
8307
+ };
8308
+ },
8309
+ focus: (op) => ({ objectId: op.objectId }),
8310
+ describe: (op) => op.changes.label ? `Renomme l'objet en \xAB ${op.changes.label} \xBB` : "Modifie l'objet"
8311
+ });
8312
+ var removeObjectSchema = z.object({ ...objectOperationBase, type: z.literal("remove_object") });
8313
+ var removeObject = defineOperation({
8314
+ type: "remove_object",
8315
+ schema: removeObjectSchema,
8316
+ apply: (state, op) => {
8317
+ requireObject(state, op.objectId);
8318
+ const objectName = state.objects.find((o) => o.id === op.objectId)?.name;
8319
+ return {
8320
+ ...state,
8321
+ objects: state.objects.filter((o) => o.id !== op.objectId),
8322
+ attributes: state.attributes.filter((a) => a.objectId !== op.objectId),
8323
+ sampleRecords: state.sampleRecords.filter((r) => r.objectId !== op.objectId),
8324
+ views: state.views.filter((v) => v.objectName !== objectName)
8325
+ };
8326
+ },
8327
+ focus: () => ({}),
8328
+ describe: (op) => `Supprime l'objet ${op.objectId}`
8329
+ });
8330
+ var addAttributeSchema = z.object({
8331
+ ...objectOperationBase,
8332
+ type: z.literal("add_attribute"),
8333
+ attributeId: z.string().min(1),
8334
+ name: z.string().min(1),
8335
+ label: z.string().min(1),
8336
+ attributeType: z.string().min(1)
8337
+ });
8338
+ var addAttribute = defineOperation({
8339
+ type: "add_attribute",
8340
+ schema: addAttributeSchema,
8341
+ apply: (state, op) => {
8342
+ requireObject(state, op.objectId);
8343
+ if (state.attributes.some((a) => a.objectId === op.objectId && a.name === op.name)) {
8344
+ throw new ValidationError(
8345
+ `Attribute "${op.name}" already exists on object "${op.objectId}"`,
8346
+ []
8347
+ );
8348
+ }
8349
+ return {
8350
+ ...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
+ ]
8361
+ };
8362
+ },
8363
+ focus: (op) => ({ objectId: op.objectId }),
8364
+ describe: (op) => `Ajoute l'attribut \xAB ${op.label} \xBB`
8365
+ });
8366
+ var updateAttributeSchema = z.object({
8367
+ ...objectOperationBase,
8368
+ type: z.literal("update_attribute"),
8369
+ attributeId: z.string().min(1),
8370
+ changes: z.object({ label: z.string().min(1).optional() }).refine((c) => Object.keys(c).length > 0, "update_attribute needs at least one change")
8371
+ });
8372
+ var updateAttribute = defineOperation({
8373
+ type: "update_attribute",
8374
+ schema: updateAttributeSchema,
8375
+ apply: (state, op) => {
8376
+ if (!state.attributes.some((a) => a.id === op.attributeId)) {
8377
+ throw new ValidationError(`Attribute "${op.attributeId}" is not in the draftable state`, []);
8378
+ }
8379
+ return {
8380
+ ...state,
8381
+ attributes: state.attributes.map(
8382
+ (a) => a.id === op.attributeId ? { ...a, ...op.changes } : a
8383
+ )
8384
+ };
8385
+ },
8386
+ // Carries objectId so the scope can load the attribute's parent. Without it
8387
+ // the reader returns an empty state and the fold rejects the operation before
8388
+ // the draft is ever persisted — renaming an existing field was impossible.
8389
+ focus: (op) => ({ objectId: op.objectId }),
8390
+ describe: (op) => op.changes.label ? `Renomme l'attribut en \xAB ${op.changes.label} \xBB` : "Modifie l'attribut"
8391
+ });
8392
+ var removeAttributeSchema = z.object({
8393
+ ...objectOperationBase,
8394
+ type: z.literal("remove_attribute"),
8395
+ attributeId: z.string().min(1)
8396
+ });
8397
+ var removeAttribute = defineOperation({
8398
+ type: "remove_attribute",
8399
+ schema: removeAttributeSchema,
8400
+ apply: (state, op) => {
8401
+ if (!state.attributes.some((a) => a.id === op.attributeId)) {
8402
+ throw new ValidationError(`Attribute "${op.attributeId}" is not in the draftable state`, []);
8403
+ }
8404
+ return { ...state, attributes: state.attributes.filter((a) => a.id !== op.attributeId) };
8405
+ },
8406
+ // Same reason as update_attribute: the parent object must be in scope.
8407
+ focus: (op) => ({ objectId: op.objectId }),
8408
+ describe: (op) => `Supprime l'attribut ${op.attributeId}`
8409
+ });
8410
+ var addSampleRecordSchema = z.object({
8411
+ ...objectOperationBase,
8412
+ type: z.literal("add_sample_record"),
8413
+ recordId: z.string().min(1),
8414
+ values: z.record(z.string(), z.unknown())
8415
+ });
8416
+ var addSampleRecord = defineOperation({
8417
+ type: "add_sample_record",
8418
+ schema: addSampleRecordSchema,
8419
+ apply: (state, op) => {
8420
+ requireObject(state, op.objectId);
8421
+ if (state.sampleRecords.some((r) => r.id === op.recordId)) {
8422
+ throw new ValidationError(`Sample record "${op.recordId}" already exists`, []);
8423
+ }
8424
+ return {
8425
+ ...state,
8426
+ sampleRecords: [
8427
+ ...state.sampleRecords,
8428
+ { id: op.recordId, objectId: op.objectId, values: op.values }
8429
+ ]
8430
+ };
8431
+ },
8432
+ // A sample is a draft record, not a render-time fiction: publishing
8433
+ // materialises it, discarding the draft discards it.
8434
+ focus: (op) => ({ objectId: op.objectId, recordId: op.recordId }),
8435
+ describe: () => "Ajoute un exemple"
8436
+ });
8437
+ var removeSampleRecordSchema = z.object({
8438
+ ...operationBase,
8439
+ type: z.literal("remove_sample_record"),
8440
+ recordId: z.string().min(1)
8441
+ });
8442
+ var removeSampleRecord = defineOperation({
8443
+ type: "remove_sample_record",
8444
+ schema: removeSampleRecordSchema,
8445
+ 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`, []);
8448
+ }
8449
+ return { ...state, sampleRecords: state.sampleRecords.filter((r) => r.id !== op.recordId) };
8450
+ },
8451
+ focus: () => ({}),
8452
+ describe: () => "Retire un exemple"
8453
+ });
8454
+ var SCHEMA_OPERATIONS = [
8455
+ addObject,
8456
+ updateObject,
8457
+ removeObject,
8458
+ addAttribute,
8459
+ updateAttribute,
8460
+ removeAttribute,
8461
+ addSampleRecord,
8462
+ removeSampleRecord
8463
+ ];
8464
+
8465
+ // src/architect/registry.ts
8466
+ function build() {
8467
+ const map = /* @__PURE__ */ new Map();
8468
+ for (const definition of [
8469
+ ...SCHEMA_OPERATIONS,
8470
+ ...DETAIL_VIEW_OPERATIONS,
8471
+ ...LIST_VIEW_OPERATIONS
8472
+ ]) {
8473
+ if (map.has(definition.type)) {
8474
+ throw new DuplicateError("architect operation", definition.type);
8475
+ }
8476
+ map.set(definition.type, definition);
8477
+ }
8478
+ return map;
8479
+ }
8480
+ var OPERATION_REGISTRY = build();
8481
+ var ALL_OPERATION_TYPES = [...OPERATION_REGISTRY.keys()];
8482
+
8483
+ // src/architect/apply.ts
8484
+ function defOf(operation) {
8485
+ const definition = OPERATION_REGISTRY.get(operation.type);
8486
+ if (!definition) {
8487
+ throw new ValidationError(
8488
+ `Operation "${operation.id}" has unknown type "${operation.type}"`,
8489
+ []
8490
+ );
8491
+ }
8492
+ return definition;
8493
+ }
8494
+ function applyOperations(state, operations) {
8495
+ return operations.reduce(
8496
+ (acc, operation) => defOf(operation).apply(acc, operation),
8497
+ state
8498
+ );
8499
+ }
8500
+ function focusOf(operation) {
8501
+ return defOf(operation).focus(operation);
8502
+ }
8503
+ function describeOperations(operations, ctx) {
8504
+ return operations.map((operation) => defOf(operation).describe(operation, ctx));
8505
+ }
8506
+ function parseOperation(candidate) {
8507
+ if (typeof candidate !== "object" || candidate === null || !("type" in candidate)) {
8508
+ throw new ValidationError("An operation must be an object carrying a type", []);
8509
+ }
8510
+ const type = candidate.type;
8511
+ if (typeof type !== "string") {
8512
+ throw new ValidationError("An operation's type must be a string", []);
8513
+ }
8514
+ const definition = OPERATION_REGISTRY.get(type);
8515
+ if (!definition) {
8516
+ throw new ValidationError(`Unknown operation type "${type}"`, []);
8517
+ }
8518
+ const parsed = definition.schema.safeParse(candidate);
8519
+ if (!parsed.success) {
8520
+ throw new ValidationError(
8521
+ `Operation "${type}" is invalid: ${parsed.error.issues.map((i) => `${i.path.join(".")} ${i.message}`).join("; ")}`,
8522
+ []
8523
+ );
8524
+ }
8525
+ return parsed.data;
8526
+ }
8527
+
8528
+ // src/architect/field-ids.ts
8529
+ function makeFieldId(groupId, seed, collisionIndex) {
8530
+ const base = `fld_${groupId}_${seed}`;
8531
+ return collisionIndex === 0 ? base : `${base}_${collisionIndex}`;
8532
+ }
8533
+ function seedOf(field, index) {
8534
+ if (field.attributeGroup) return field.attributeGroup.id;
8535
+ if (field.attribute) return field.attribute;
8536
+ return `slot${index}`;
8537
+ }
8538
+ function withIds(group2) {
8539
+ const seen = /* @__PURE__ */ new Map();
8540
+ const fields = group2.fields.map((field, index) => {
8541
+ if (field.id) return field;
8542
+ const seed = seedOf(field, index);
8543
+ const collisionIndex = seen.get(seed) ?? 0;
8544
+ seen.set(seed, collisionIndex + 1);
8545
+ return { ...field, id: makeFieldId(group2.id, seed, collisionIndex) };
8546
+ });
8547
+ return { ...group2, fields };
8548
+ }
8549
+ function ensureFieldIds(tabs) {
8550
+ return tabs.map(
8551
+ (tab) => tab.type === "form" ? { ...tab, groups: tab.groups.map(withIds) } : tab
8552
+ );
8553
+ }
8554
+
8555
+ // src/architect/view-projection.ts
8556
+ function toDraftableView(view) {
8557
+ return {
8558
+ id: view.id ?? "",
8559
+ objectName: view.object,
8560
+ type: view.type,
8561
+ label: view.label,
8562
+ tabs: isDetailView(view) ? view.config.tabs ?? [] : [],
8563
+ config: view.config
8564
+ };
8565
+ }
8566
+ function fromDraftableView(original, drafted) {
8567
+ if (original.type === "detail") {
8568
+ return {
8569
+ ...original,
8570
+ label: drafted.label,
8571
+ config: {
8572
+ ...drafted.config,
8573
+ tabs: drafted.tabs
8574
+ }
8575
+ };
8576
+ }
8577
+ return {
8578
+ ...original,
8579
+ label: drafted.label,
8580
+ config: drafted.config
8581
+ };
8582
+ }
8583
+
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 };