@stndrds/schema 1.0.0-alpha.276 → 1.0.0-alpha.278

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 (73) hide show
  1. package/dist/{all-D5zeUllO.d.mts → all-BSeTO0fj.d.mts} +20 -3
  2. package/dist/{all--B2_3ksI.d.ts → all-DoYgTt64.d.ts} +20 -3
  3. package/dist/{attributes-_b3Db8vT.d.ts → attributes-Da15v-sw.d.ts} +1 -1
  4. package/dist/{attributes-lBLiOIY3.d.mts → attributes-VsYmgI0A.d.mts} +1 -1
  5. package/dist/{chunk-4USPA67J.mjs → chunk-5PLJHYSL.mjs} +139 -26
  6. package/dist/{chunk-T7BST4JS.js → chunk-DEHBEFGO.js} +3 -3
  7. package/dist/{chunk-RAF6K6VG.js → chunk-NELH4AXI.js} +30 -18
  8. package/dist/{chunk-U7QUIEFF.mjs → chunk-PQEOIDXD.mjs} +1 -1
  9. package/dist/{chunk-EDOEX3O7.js → chunk-QMAVKX3Y.js} +178 -55
  10. package/dist/{chunk-QLU5QR7M.mjs → chunk-V2WJFUZW.mjs} +16 -8
  11. package/dist/{chunk-RBG2YMF2.mjs → chunk-YCWGUPSI.mjs} +26 -16
  12. package/dist/{chunk-F3YPU2N6.js → chunk-ZBWTAKZO.js} +16 -8
  13. package/dist/exceptions.d.mts +15 -10
  14. package/dist/exceptions.d.ts +15 -10
  15. package/dist/exceptions.js +39 -39
  16. package/dist/exceptions.mjs +1 -1
  17. package/dist/{helpers-C1VVEAOO.d.mts → helpers-BYhVd4Gw.d.mts} +3 -3
  18. package/dist/{helpers-vQ6kp8ET.d.ts → helpers-D2cL7hI2.d.ts} +3 -3
  19. package/dist/index-CixTESyP.d.mts +790 -0
  20. package/dist/index-dJ6fAwcG.d.ts +790 -0
  21. package/dist/index.d.mts +2662 -433
  22. package/dist/index.d.ts +2662 -433
  23. package/dist/index.js +641 -391
  24. package/dist/index.mjs +416 -223
  25. package/dist/{migrations-BXd2ZGfM.d.mts → migrations-Dy9K8kJ0.d.mts} +1 -1
  26. package/dist/{migrations-DcuJZ8qO.d.ts → migrations-hbZHm8Tm.d.ts} +1 -1
  27. package/dist/{objects-BCaBw2ef.d.mts → objects-Cvt2T2Q5.d.mts} +19 -3
  28. package/dist/{objects-A1ED9af-.d.ts → objects-_6M6ngH3.d.ts} +19 -3
  29. package/dist/{types-DNz3ITS-.d.mts → types-CX7S3Fhh.d.mts} +1 -1
  30. package/dist/{types-DqLi1tx1.d.ts → types-DseDsbMu.d.ts} +1 -1
  31. package/dist/validation/all.d.mts +7 -7
  32. package/dist/validation/all.d.ts +7 -7
  33. package/dist/validation/all.js +33 -33
  34. package/dist/validation/all.mjs +8 -8
  35. package/dist/validation/complex/currency.d.mts +2 -2
  36. package/dist/validation/complex/currency.d.ts +2 -2
  37. package/dist/validation/complex/location.d.mts +2 -2
  38. package/dist/validation/complex/location.d.ts +2 -2
  39. package/dist/validation/complex/phone.d.mts +2 -2
  40. package/dist/validation/complex/phone.d.ts +2 -2
  41. package/dist/validation/complex/relation.d.mts +2 -2
  42. package/dist/validation/complex/relation.d.ts +2 -2
  43. package/dist/validation/complex/richtext.d.mts +2 -2
  44. package/dist/validation/complex/richtext.d.ts +2 -2
  45. package/dist/validation/complex/select.d.mts +2 -2
  46. package/dist/validation/complex/select.d.ts +2 -2
  47. package/dist/validation/complex/user.d.mts +2 -2
  48. package/dist/validation/complex/user.d.ts +2 -2
  49. package/dist/validation/computed/formula.d.mts +2 -2
  50. package/dist/validation/computed/formula.d.ts +2 -2
  51. package/dist/validation/computed/rollup.d.mts +2 -2
  52. package/dist/validation/computed/rollup.d.ts +2 -2
  53. package/dist/validation/config/index.d.mts +4 -4
  54. package/dist/validation/config/index.d.ts +4 -4
  55. package/dist/validation/config/index.js +11 -11
  56. package/dist/validation/config/index.mjs +2 -2
  57. package/dist/validation/core/index.d.mts +3 -3
  58. package/dist/validation/core/index.d.ts +3 -3
  59. package/dist/validation/object/index.d.mts +5 -5
  60. package/dist/validation/object/index.d.ts +5 -5
  61. package/dist/validation/object/index.js +18 -18
  62. package/dist/validation/object/index.mjs +6 -6
  63. package/dist/validation/primitives/checkbox.d.mts +2 -2
  64. package/dist/validation/primitives/checkbox.d.ts +2 -2
  65. package/dist/validation/primitives/date.d.mts +2 -2
  66. package/dist/validation/primitives/date.d.ts +2 -2
  67. package/dist/validation/primitives/number.d.mts +2 -2
  68. package/dist/validation/primitives/number.d.ts +2 -2
  69. package/dist/validation/primitives/text.d.mts +2 -2
  70. package/dist/validation/primitives/text.d.ts +2 -2
  71. package/package.json +2 -2
  72. package/dist/index-Bq1KrQkR.d.ts +0 -2413
  73. package/dist/index-DtxtOBYT.d.mts +0 -2413
package/dist/index.mjs CHANGED
@@ -1,26 +1,26 @@
1
1
  import { generateId } from './chunk-QY6QFRRV.mjs';
2
2
  export { asTenantId, asUserId, deepEqual, generateId, indexBy } from './chunk-QY6QFRRV.mjs';
3
- import { SYSTEM_FILTER_ATTRIBUTE_TYPES, RESERVED_OBJECT_NAMES, listViewConfigSchema, detailViewConfigSchema, RESERVED_ATTRIBUTE_NAMES, isAttributeSortable, getAttributeCapabilities, resolveIsWithinBounds } from './chunk-4USPA67J.mjs';
4
- export { ATTRIBUTE_FILTER_OPERATORS, LIST_VIEW_TAB_VISIBILITIES, NO_VALUE_OPERATORS, OPERATORS_BY_TYPE, REMOVED_OPERATOR_REPLACEMENTS, RESERVED_ATTRIBUTE_NAMES, RESERVED_OBJECT_NAMES, RESOURCE_VISIBILITIES, SYNONYM_ALIASES, SYSTEM_ATTRIBUTES, SYSTEM_ATTRIBUTE_I18N_KEYS, SYSTEM_FIELD_NAMES, SYSTEM_FILTER_ATTRIBUTE_TYPES, collectQualifiedRuleIssues, currentActor, detailTabSchema, detailViewConfigSchema, getAttributeCapabilities, getAttributeFilterOperators, getRollupFilterOperators, getSystemAttributeI18nKey, getSystemAttributeList, inverseSourceSchema, isAttributeFilterable, isAttributeGroupable, isAttributeKanbanGroupable, isAttributeSearchable, isDynamicValue, isManagedSystemAttribute, isNoValueOperator, isRelativeDateValue, listViewConfigSchema, listViewTabSchema, normalizeFilterRule, normalizeOperator, now, parseViewConfig, relationSourceSchema, resolveIsWithinBounds, tableSourceSchema, toUtcDayString, today, validateQualifiedRule, viewConfigByTypeSchema, viewTypeSchema } from './chunk-4USPA67J.mjs';
5
- import { iconNameSchema, parseAttributeConfigForCreate, parseComputedFormula } from './chunk-U7QUIEFF.mjs';
6
- export { ComputedFormulaParseError, SCHEMA_LIMITS, colorIdSchema, iconNameSchema, multiselectOptionWriteSchema, parseAttributeConfig, parseAttributeConfigForCreate, parseAttributeConfigForUpdate, parseComputedFormula, selectOptionWriteSchema, statusGroupSchema, statusOptionWriteSchema } from './chunk-U7QUIEFF.mjs';
7
- import { createObjectValidator, createAttributeValidator } from './chunk-RBG2YMF2.mjs';
8
- export { createFormAttributeValidator, rejectUnknownAttributesOrThrow, validateDraft, validateDraftOrThrow, validateObject, validateObjectOrThrow } from './chunk-RBG2YMF2.mjs';
3
+ import { SYSTEM_FILTER_ATTRIBUTE_TYPES, RESERVED_OBJECT_NAMES, listViewConfigSchema, detailViewConfigSchema, RESERVED_ATTRIBUTE_NAMES, isAttributeSortable, getAttributeCapabilities, resolveIsWithinBounds, normalizeForEdgeRpc, getOperatorPolarity, extractCurrencyFilterValue } from './chunk-5PLJHYSL.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-5PLJHYSL.mjs';
5
+ import { iconNameSchema, parseAttributeConfigForCreate, parseComputedFormula } from './chunk-PQEOIDXD.mjs';
6
+ export { ComputedFormulaParseError, SCHEMA_LIMITS, colorIdSchema, iconNameSchema, multiselectOptionWriteSchema, parseAttributeConfig, parseAttributeConfigForCreate, parseAttributeConfigForUpdate, parseComputedFormula, selectOptionWriteSchema, statusGroupSchema, statusOptionWriteSchema } from './chunk-PQEOIDXD.mjs';
7
+ import { createObjectValidator, createAttributeValidator, isNullishOrEmptyString } from './chunk-YCWGUPSI.mjs';
8
+ export { createFormAttributeValidator, isNullishOrEmptyString, isValuePresent, rejectUnknownAttributesOrThrow, validateDraft, validateDraftOrThrow, validateObject, validateObjectOrThrow } from './chunk-YCWGUPSI.mjs';
9
+ import { formatPhoneForDisplay, normalizeCountrylessPhoneNumber, normalizePhoneNumber } from './chunk-R5LAJCBU.mjs';
10
+ import './chunk-GO6LQADH.mjs';
9
11
  import './chunk-QVLQPW3O.mjs';
10
12
  import './chunk-ZDQ5AP26.mjs';
11
13
  import './chunk-LV3FEUKU.mjs';
12
- import './chunk-UXAHLSWC.mjs';
13
- import './chunk-NS63SPNN.mjs';
14
14
  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, NotFoundError, DuplicateError } from './chunk-QLU5QR7M.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-QLU5QR7M.mjs';
18
+ import { SchemaError, SchemaErrorCode, ValidationError, DuplicateError, NotFoundError } from './chunk-V2WJFUZW.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-V2WJFUZW.mjs';
20
+ import './chunk-UXAHLSWC.mjs';
21
+ import './chunk-NS63SPNN.mjs';
20
22
  import './chunk-AYVHMVKQ.mjs';
21
23
  import './chunk-YUFTHPOE.mjs';
22
- 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';
@@ -136,6 +136,44 @@ var AUDIT_ACTIONS = [
136
136
  ];
137
137
 
138
138
  // src/types/agent.ts
139
+ function isTerminalState(state) {
140
+ return state.phase === "terminal";
141
+ }
142
+ function sessionStateToLegacyStatus(state) {
143
+ switch (state.phase) {
144
+ case "running":
145
+ return "active";
146
+ case "queued":
147
+ return "idle";
148
+ case "parked":
149
+ if (state.parkedOn === void 0) {
150
+ throw new SchemaError("parked state without parkedOn", SchemaErrorCode.INVARIANT_VIOLATION);
151
+ }
152
+ return state.parkedOn === "agents" ? "waiting_agents" : "waiting_human";
153
+ case "terminal":
154
+ if (state.outcome === void 0) {
155
+ throw new SchemaError(
156
+ "terminal state without outcome",
157
+ SchemaErrorCode.INVARIANT_VIOLATION
158
+ );
159
+ }
160
+ return state.outcome;
161
+ }
162
+ }
163
+ function legacyStatusToSessionState(status2) {
164
+ switch (status2) {
165
+ case "active":
166
+ return { phase: "running" };
167
+ case "idle":
168
+ return { phase: "queued" };
169
+ case "waiting_human":
170
+ return { phase: "parked", parkedOn: "human", humanRequestIds: [] };
171
+ case "waiting_agents":
172
+ return { phase: "parked", parkedOn: "agents" };
173
+ default:
174
+ return { phase: "terminal", outcome: status2 };
175
+ }
176
+ }
139
177
  var SESSION_TERMINAL_STATUSES = [
140
178
  "completed",
141
179
  "failed",
@@ -151,7 +189,7 @@ var DEFAULT_APPROVAL_POLICY = Object.freeze({
151
189
  destructive: "ask",
152
190
  outward: "ask"
153
191
  });
154
- var TODO_PLAN_STATUSES = ["active", "completed", "promoted", "abandoned"];
192
+ var TODO_PLAN_STATUSES = ["active", "completed", "abandoned"];
155
193
  function agentDisplayName(agent2) {
156
194
  return agent2.label?.trim() || agent2.name;
157
195
  }
@@ -161,6 +199,60 @@ var MAX_TODO_ID_CHARS = 80;
161
199
  var MAX_TODO_DESCRIPTION_CHARS = 500;
162
200
  var MAX_TODO_RESULT_CHARS = 2e3;
163
201
 
202
+ // src/types/agent-ui-data.ts
203
+ var NATIVE_AGENT_UI_PART_IDS_METADATA_KEY = "__stndrdsNativeUiPartIds";
204
+ var NATIVE_AGENT_UI_PART_IDS_METADATA_SCHEMA_VERSION = 1;
205
+ var INVALID_NATIVE_PART_IDS = "Native agent UI part IDs metadata is invalid";
206
+ function invalidNativePartIds() {
207
+ throw new ValidationError(INVALID_NATIVE_PART_IDS, []);
208
+ }
209
+ function isPlainRecord(value) {
210
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
211
+ const prototype = Object.getPrototypeOf(value);
212
+ return prototype === Object.prototype || prototype === null;
213
+ }
214
+ function nativeAgentUIPartIdMetadataKey(part, partIndex) {
215
+ if (part.type === "text" || part.type === "reasoning") return `${part.type}:${partIndex}`;
216
+ if (part.type === "tool") return `tool:${part.toolCallId}`;
217
+ return void 0;
218
+ }
219
+ function parseNativeAgentUIPartIdsMetadata(message) {
220
+ const stored = message.metadata?.[NATIVE_AGENT_UI_PART_IDS_METADATA_KEY];
221
+ if (!isPlainRecord(stored)) invalidNativePartIds();
222
+ if (Object.keys(stored).length !== 2 || stored.schemaVersion !== NATIVE_AGENT_UI_PART_IDS_METADATA_SCHEMA_VERSION || !isPlainRecord(stored.partIds)) {
223
+ invalidNativePartIds();
224
+ }
225
+ const expected = /* @__PURE__ */ new Map();
226
+ for (const [index, part] of message.parts.entries()) {
227
+ const key = nativeAgentUIPartIdMetadataKey(part, index);
228
+ if (!key || expected.has(key)) {
229
+ if (key) invalidNativePartIds();
230
+ continue;
231
+ }
232
+ expected.set(key, part);
233
+ }
234
+ const entries = Object.entries(stored.partIds);
235
+ if (entries.length !== expected.size) invalidNativePartIds();
236
+ const nativeIdTypes = /* @__PURE__ */ new Map();
237
+ const parsed = {};
238
+ for (const [key, value] of entries) {
239
+ const part = expected.get(key);
240
+ if (!(part && typeof value === "string" && value.length > 0)) {
241
+ invalidNativePartIds();
242
+ }
243
+ const existingType = nativeIdTypes.get(value);
244
+ if (existingType && (part.type === "tool" || existingType !== part.type)) {
245
+ invalidNativePartIds();
246
+ }
247
+ if (part.type === "tool" && value !== part.toolCallId) {
248
+ invalidNativePartIds();
249
+ }
250
+ nativeIdTypes.set(value, part.type);
251
+ parsed[key] = value;
252
+ }
253
+ return parsed;
254
+ }
255
+
164
256
  // src/types/document-layout.ts
165
257
  var MAX_PRESET_DEPTH = 5;
166
258
 
@@ -197,6 +289,10 @@ function isFormSlotFieldRef(f) {
197
289
  function isFormFreeFieldRef(f) {
198
290
  return f.type === "free";
199
291
  }
292
+ function resolveFieldRequired(input) {
293
+ if (input.fieldRequired !== void 0) return input.fieldRequired;
294
+ return input.slotMode === "create" && input.attributeRequired === true;
295
+ }
200
296
  function getSlotFieldTargets(field) {
201
297
  return field.additionalSlotIds?.length ? [field.slotId, ...field.additionalSlotIds] : [field.slotId];
202
298
  }
@@ -262,6 +358,7 @@ function hasOptions(attr) {
262
358
 
263
359
  // src/types/user-profiles.ts
264
360
  var USER_STATUSES = ["active", "suspended"];
361
+ var USER_WORK_POSTURES = ["plan", "manual", "auto"];
265
362
 
266
363
  // src/types/schema-state.ts
267
364
  function viewStateKey(view) {
@@ -283,6 +380,20 @@ function isRelationGroup(group2) {
283
380
  }
284
381
 
285
382
  // src/types/pagination.ts
383
+ var COUNT_MODES = ["none", "estimated", "exact"];
384
+ function parseCountMode(value) {
385
+ if (typeof value === "string" && COUNT_MODES.includes(value)) {
386
+ return value;
387
+ }
388
+ 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) + ")",
391
+ []
392
+ );
393
+ }
394
+ function parseOptionalCountMode(value) {
395
+ return value === void 0 ? void 0 : parseCountMode(value);
396
+ }
286
397
  var ESTIMATED_COUNT_CAP = 1e4;
287
398
 
288
399
  // src/lib/object-helpers.ts
@@ -381,7 +492,7 @@ function isDateRangeValue(value) {
381
492
  return typeof value === "object" && value !== null && typeof value.start === "string";
382
493
  }
383
494
  function normalizeDateValue(value, attr) {
384
- if (value == null || value === "") return null;
495
+ if (isNullishOrEmptyString(value)) return null;
385
496
  if (isDateRangeValue(value)) {
386
497
  return attr.endDate ? { start: value.start, end: value.end ?? null } : value.start;
387
498
  }
@@ -519,7 +630,7 @@ function formatMultiselect(value, attribute) {
519
630
  return value.join(", ");
520
631
  }
521
632
  function formatAttributeValue(value, attribute) {
522
- if (value === null || value === void 0 || value === "") {
633
+ if (isNullishOrEmptyString(value)) {
523
634
  return EMPTY_VALUE_PLACEHOLDER;
524
635
  }
525
636
  switch (attribute.type) {
@@ -666,32 +777,40 @@ function renderLabelExpression(template, values, fallback = DEFAULT_LABEL_FALLBA
666
777
  const alternatives = orParts.filter(Boolean);
667
778
  let value = "";
668
779
  for (const alt of alternatives) {
669
- const v = getValue(values, alt);
670
- if (v != null && v !== "") {
671
- value = v;
780
+ const text2 = toText(getValue(values, alt));
781
+ if (text2 !== "") {
782
+ value = text2;
672
783
  break;
673
784
  }
674
785
  }
675
- const isEmpty2 = value == null || value === "";
786
+ const isEmpty2 = isNullishOrEmptyString(value);
676
787
  if (isEmpty2 && pipes.length === 0) return "";
677
788
  for (const pipeExpr of pipes) {
678
789
  const { name: pipeName, args } = parsePipeExpression(pipeExpr);
679
790
  const simpleFn = simplePipes[pipeName];
680
791
  if (simpleFn) {
681
- if (value != null && value !== "") {
682
- value = simpleFn(String(value));
792
+ if (value !== "") {
793
+ value = simpleFn(value);
683
794
  }
684
795
  } else {
685
796
  const argFn = pipesWithArgs[pipeName];
686
797
  if (argFn) {
687
- value = argFn(String(value ?? ""), ...args);
798
+ value = argFn(value, ...args);
688
799
  }
689
800
  }
690
801
  }
691
- return String(value ?? "");
802
+ return value;
692
803
  }).trim();
693
804
  return result || fallback;
694
805
  }
806
+ function toText(value) {
807
+ if (value == null) return "";
808
+ if (typeof value === "function") return "";
809
+ if (typeof value !== "object") return String(value);
810
+ if (Array.isArray(value)) return value.map(toText).filter(Boolean).join(",");
811
+ const ownToString = value.toString;
812
+ return typeof ownToString === "function" && ownToString !== Object.prototype.toString ? String(value) : "";
813
+ }
695
814
  function isLabelExpression(value) {
696
815
  return /\{\{\s*\S+.*\}\}/.test(value);
697
816
  }
@@ -741,7 +860,7 @@ function relationPropertyDefs(attribute) {
741
860
  return attribute.properties?.definitions;
742
861
  }
743
862
  function extractValueRefs(value) {
744
- if (value === null || value === void 0 || value === "") return [];
863
+ if (isNullishOrEmptyString(value)) return [];
745
864
  if (typeof value === "string") return [{ id: value }];
746
865
  if (Array.isArray(value)) return value.flatMap((item) => extractValueRefs(item));
747
866
  if (typeof value === "object" && "id" in value) {
@@ -753,11 +872,26 @@ function extractValueRefs(value) {
753
872
 
754
873
  // src/lib/user-display.ts
755
874
  function getUserDisplayName(user2) {
756
- if (user2.firstName || user2.lastName) {
757
- return [user2.firstName, user2.lastName].filter(Boolean).join(" ");
875
+ const named = [user2.firstName, user2.lastName].map((part) => part?.trim()).filter(Boolean).join(" ");
876
+ if (named !== "") {
877
+ return named;
758
878
  }
759
879
  return user2.email?.split("@")[0] ?? "";
760
880
  }
881
+ var INITIAL_CHARACTER = /\p{L}|\p{N}/u;
882
+ function deriveInitials(label, fallback) {
883
+ const trimmed = label?.trim() ?? "";
884
+ if (trimmed === "") {
885
+ return fallback;
886
+ }
887
+ const words = trimmed.split(/\s+/);
888
+ const parts = words.length === 1 ? trimmed.split("@")[0].split(/[._-]/) : words;
889
+ const initials = parts.map((part) => {
890
+ const initial = part.match(INITIAL_CHARACTER)?.[0];
891
+ return initial === void 0 ? "" : [...initial.toUpperCase()][0] ?? "";
892
+ }).filter(Boolean).slice(0, 2).join("");
893
+ return initials === "" ? fallback : initials;
894
+ }
761
895
 
762
896
  // src/lib/record-creator.ts
763
897
  var RECORD_CREATOR_ROOT_ACTOR_METADATA_KEY = "__creatorRootActorId";
@@ -766,6 +900,20 @@ function getRecordCreatorPrincipalId(record) {
766
900
  return typeof creatorRootActorId === "string" && creatorRootActorId.length > 0 ? creatorRootActorId : record.createdBy;
767
901
  }
768
902
 
903
+ // src/lib/action-grant.ts
904
+ function includesAction(actions, action) {
905
+ return actions?.includes("*") === true || actions?.includes(action) === true;
906
+ }
907
+ function buildPermissionFlags(actions) {
908
+ return {
909
+ canRead: includesAction(actions, "read"),
910
+ canCreate: includesAction(actions, "create"),
911
+ canUpdate: includesAction(actions, "update"),
912
+ canDelete: includesAction(actions, "delete"),
913
+ canManage: includesAction(actions, "manage")
914
+ };
915
+ }
916
+
769
917
  // src/constants/attribute-columns.ts
770
918
  var DB_COLUMN_FIELDS = /* @__PURE__ */ new Set([
771
919
  "id",
@@ -905,6 +1053,7 @@ function isDefaultRole(roleName) {
905
1053
  }
906
1054
  var VALID_ICONS = new Set(ICONS);
907
1055
  var ATTRIBUTE_NAME_REGEX = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
1056
+ var VIEW_NAME_REGEX = /^[a-z][a-z0-9-]*$/;
908
1057
  var MAX_NAME_LENGTH = 63;
909
1058
  var MAX_LABEL_LENGTH = 128;
910
1059
  var OBJECT_NAME_SCHEMA = z2.string().min(1, "Object name cannot be empty").max(63, "Object name is too long (max 63 characters)").regex(/^[a-z][a-z0-9-]*$/, {
@@ -920,6 +1069,26 @@ function validateObjectName(name) {
920
1069
  throw error;
921
1070
  }
922
1071
  }
1072
+ function validateViewName(name) {
1073
+ if (!name || name.length === 0) {
1074
+ throw new ValidationError("View name cannot be empty", [
1075
+ { path: ["name"], message: "View name cannot be empty" }
1076
+ ]);
1077
+ }
1078
+ if (name.length > MAX_NAME_LENGTH) {
1079
+ throw new ValidationError("View name is too long", [
1080
+ { path: ["name"], message: `View name is too long (max ${MAX_NAME_LENGTH} characters)` }
1081
+ ]);
1082
+ }
1083
+ if (!VIEW_NAME_REGEX.test(name)) {
1084
+ throw new ValidationError("Invalid view name format", [
1085
+ {
1086
+ path: ["name"],
1087
+ message: "View name must be in kebab-case (e.g., 'detail', 'list-view')"
1088
+ }
1089
+ ]);
1090
+ }
1091
+ }
923
1092
  function assertUniqueBy(items, getKey, buildError) {
924
1093
  const seen = /* @__PURE__ */ new Set();
925
1094
  for (const item of items) {
@@ -1076,6 +1245,25 @@ var AgentBuilder = class {
1076
1245
  Object.assign(this.bp, value);
1077
1246
  return this;
1078
1247
  }
1248
+ /**
1249
+ * Opt this agent into MCP servers: an array of server ids, or `"all"` to
1250
+ * mount every server the viewer can see. Absent by default — an agent that
1251
+ * never calls this stays tool-identical to one that predates the feature.
1252
+ * The opt-in only narrows; visibility is still enforced below it at
1253
+ * resolution time (`buildMcpToolset`), so naming an id the viewer cannot
1254
+ * see yields no tools from it, not an error.
1255
+ *
1256
+ * @example
1257
+ * ```typescript
1258
+ * agent({ name: "research-assistant" })
1259
+ * .mcpServers(["notion-workspace"])
1260
+ * // ...
1261
+ * ```
1262
+ */
1263
+ mcpServers(value) {
1264
+ this.bp.mcpServers = Array.isArray(value) ? [...value] : value;
1265
+ return this;
1266
+ }
1079
1267
  approval(value) {
1080
1268
  this.bp.approval = { ...DEFAULT_APPROVAL_POLICY, ...this.bp.approval, ...value };
1081
1269
  return this;
@@ -2544,27 +2732,55 @@ var ObjectBuilder = class {
2544
2732
  * into the TRecord generic, enabling full inference.
2545
2733
  *
2546
2734
  * @param attr - Attribute definition or builder (auto-builds if builder)
2735
+ * @throws DuplicateError if the name is already declared on this object
2547
2736
  */
2548
2737
  attribute(attr) {
2549
- if (!this.obj.attributes) {
2550
- this.obj.attributes = [];
2551
- }
2552
- const finalAttr = "build" in attr && typeof attr.build === "function" ? attr.build() : attr;
2553
- this.obj.attributes.push(finalAttr);
2738
+ this.pushAttributes([attr]);
2554
2739
  return this;
2555
2740
  }
2556
2741
  /**
2557
2742
  * Add multiple attributes at once
2558
2743
  * Note: For full type inference, prefer chaining .attribute() calls
2744
+ *
2745
+ * @throws DuplicateError if a name is declared twice, inside this batch or
2746
+ * against an attribute already declared on this object
2559
2747
  */
2560
2748
  attributes(attrs) {
2561
- if (!this.obj.attributes) {
2562
- this.obj.attributes = [];
2563
- }
2564
- const finalAttrs = attrs.map((attr) => "build" in attr ? attr.build() : attr);
2565
- this.obj.attributes.push(...finalAttrs);
2749
+ this.pushAttributes(attrs);
2566
2750
  return this;
2567
2751
  }
2752
+ /**
2753
+ * Build any builders, reject duplicate names, then commit — the single push
2754
+ * path behind `attribute()` and `attributes()`, so both entry points share
2755
+ * one builder detection and one uniqueness guarantee.
2756
+ *
2757
+ * The check runs on the resulting array (already committed + incoming), so one
2758
+ * call catches both a collision inside a single `.attributes([...])` batch and
2759
+ * one spanning several calls.
2760
+ *
2761
+ * Names are compared with raw `===`. Postgres stores `attributes.name` as
2762
+ * plain `text` under a deterministic collation, so `x` and `X` are two
2763
+ * distinct attributes there; folding case here would reject a pair the
2764
+ * database accepts.
2765
+ *
2766
+ * @throws DuplicateError with `SchemaErrorCode.DUPLICATE_ATTRIBUTE`
2767
+ * @internal
2768
+ */
2769
+ pushAttributes(attrs) {
2770
+ const finalAttrs = attrs.map(
2771
+ (attr) => "build" in attr && typeof attr.build === "function" ? attr.build() : attr
2772
+ );
2773
+ assertUniqueBy(
2774
+ [...this.obj.attributes, ...finalAttrs],
2775
+ (attribute) => attribute.name,
2776
+ (name) => new DuplicateError(
2777
+ "attribute",
2778
+ name,
2779
+ `Object "${this.obj.name}": duplicate attribute name "${name}"`
2780
+ )
2781
+ );
2782
+ this.obj.attributes.push(...finalAttrs);
2783
+ }
2568
2784
  /**
2569
2785
  * Set metadata. Merges with any previously set metadata (preserves keys
2570
2786
  * written by other builder methods like `.order()`).
@@ -2757,6 +2973,8 @@ function validatePresetStructure(presetId, nodes, depth) {
2757
2973
  }
2758
2974
  }
2759
2975
  }
2976
+
2977
+ // src/builders/view-builder.ts
2760
2978
  var GroupBuilder = class {
2761
2979
  constructor(id, label) {
2762
2980
  this.data = { type: "fields", fields: [] };
@@ -2897,22 +3115,6 @@ var RelationGroupBuilder = class {
2897
3115
  return this.data;
2898
3116
  }
2899
3117
  };
2900
- function validateViewName(name, builderName, examples) {
2901
- const viewNameSchema = z.string().min(1, "View name cannot be empty").max(63, "View name is too long (max 63 characters)").regex(/^[a-z][a-z0-9-]*$/, {
2902
- message: `Invalid view name format.
2903
- Name must be in kebab-case:
2904
- \u2705 Valid: ${examples.valid}
2905
- \u274C Invalid: ${examples.invalid}`
2906
- });
2907
- try {
2908
- viewNameSchema.parse(name);
2909
- } catch (error) {
2910
- if (error instanceof z.ZodError) {
2911
- throw new Error(`[${builderName}] ${error.issues[0].message}`);
2912
- }
2913
- throw error;
2914
- }
2915
- }
2916
3118
  var TableTabConfig = class {
2917
3119
  /** @internal */
2918
3120
  constructor(view, tabData) {
@@ -3134,13 +3336,13 @@ var ActivityTabConfig = class {
3134
3336
  return this.view.build();
3135
3337
  }
3136
3338
  };
3137
- var EmailsTabConfig = class {
3339
+ var AddressMatchedTabConfig = class {
3138
3340
  /** @internal */
3139
- constructor(view, base) {
3341
+ constructor(view, base, type) {
3140
3342
  this.view = view;
3141
- this.tabData = { ...base, type: "emails", emailAttributeIds: [] };
3343
+ this.tabData = { ...base, type, emailAttributeIds: [] };
3142
3344
  }
3143
- /** Set the text attributes whose values are matched against email participants. */
3345
+ /** Set the text attributes whose values are matched against participants. */
3144
3346
  emailAttributes(...attributeIds) {
3145
3347
  this.tabData.emailAttributeIds = attributeIds;
3146
3348
  return this;
@@ -3167,6 +3369,18 @@ var EmailsTabConfig = class {
3167
3369
  return this.view.build();
3168
3370
  }
3169
3371
  };
3372
+ var EmailsTabConfig = class extends AddressMatchedTabConfig {
3373
+ /** @internal */
3374
+ constructor(view, base) {
3375
+ super(view, base, "emails");
3376
+ }
3377
+ };
3378
+ var MeetingsTabConfig = class extends AddressMatchedTabConfig {
3379
+ /** @internal */
3380
+ constructor(view, base) {
3381
+ super(view, base, "meetings");
3382
+ }
3383
+ };
3170
3384
  var DocumentsTabConfig = class {
3171
3385
  /** @internal */
3172
3386
  constructor(view, base) {
@@ -3336,6 +3550,13 @@ var TabBuilder = class {
3336
3550
  emails() {
3337
3551
  return new EmailsTabConfig(this.view, this.base);
3338
3552
  }
3553
+ /**
3554
+ * Create a meetings tab (query-time association via email-bearing attributes)
3555
+ * @example .meetings().emailAttributes("email", "backup_email")
3556
+ */
3557
+ meetings() {
3558
+ return new MeetingsTabConfig(this.view, this.base);
3559
+ }
3339
3560
  /**
3340
3561
  * Create a forms tab to launch and track form instances linked to this record
3341
3562
  * @example .tab("forms", "Forms").forms()
@@ -3348,10 +3569,7 @@ var TabBuilder = class {
3348
3569
  };
3349
3570
  var DetailViewBuilder = class {
3350
3571
  constructor(name, label) {
3351
- validateViewName(name, "DetailViewBuilder", {
3352
- valid: "'detail', 'list-view', 'company-detail'",
3353
- invalid: "'Detail', 'listView', 'list_view'"
3354
- });
3572
+ validateViewName(name);
3355
3573
  this.data = {
3356
3574
  name,
3357
3575
  label,
@@ -3471,10 +3689,7 @@ function findProtectedTabFilterAttribute(node) {
3471
3689
  }
3472
3690
  var ListViewBuilder = class {
3473
3691
  constructor(name, label) {
3474
- validateViewName(name, "ListViewBuilder", {
3475
- valid: "'default', 'list-view', 'active-contacts'",
3476
- invalid: "'Default', 'listView', 'list_view'"
3477
- });
3692
+ validateViewName(name);
3478
3693
  this.data = {
3479
3694
  name,
3480
3695
  label,
@@ -4514,19 +4729,36 @@ var SKILL_OBJECT = object({ name: "skill", label: "Skill" }).sealed().icon("spar
4514
4729
  )
4515
4730
  ).attribute(richtext({ name: "content", label: "Content" }).defaultValue(SKILL_CONTENT_TEMPLATE)).build();
4516
4731
  var SKILL_VIEW = detailView("skill-detail", "Skill").for("skill").default().sidePanel({ attributes: ["name", "description"] }).tab("content", "Content").richtext("content").titleAttribute("name").done().tab("files", "Files").documents().done().build();
4517
- var SKILL_LIST_VIEW = listView("skill-list", "Skills").for("skill").default().tab("workspace", "Skills").default().icon("table").visibility("workspace").table().columns("name", "description").sort("name", "asc").tab("mine", "Mes skills").icon("lock").visibility("private").table().columns("name", "description").sort("name", "asc").build();
4518
- var MEMORY_OBJECT = object({ name: "memory", label: "Memory" }).sealed().icon("database").order(Number.MAX_SAFE_INTEGER).pluralLabel("Memories").labelExpression("{{ name }}").embeddingExpression("{{ name }}\n{{ description }}\n{{ content }}").attribute(text({ name: "name", label: "Name" }).maxLength(MEMORY_NAME_MAX_LENGTH).required()).attribute(
4732
+ var SKILL_LIST_VIEW = listView("skill-list", "Skills").for("skill").default().tab("workspace", "Skills").default().icon("table").visibility("workspace").table().columns("name", "description").sort("name", "asc").tab("mine", "My skills").icon("lock").visibility("private").table().columns("name", "description").sort("name", "asc").build();
4733
+ var MEMORY_OBJECT = object({ name: "memory", label: "Memory" }).sealed().icon("database").order(Number.MAX_SAFE_INTEGER).pluralLabel("Memories").labelExpression("{{ name }}").embeddingExpression("{{ name }}\n{{ description }}\n{{ content }}").migration(2, (migration) => migration.changeType("content", "text", "richtext")).attribute(text({ name: "name", label: "Name" }).maxLength(MEMORY_NAME_MAX_LENGTH).required()).attribute(
4519
4734
  text({ name: "description", label: "Description" }).multiline().maxLength(MEMORY_DESCRIPTION_MAX_LENGTH).required()
4520
- ).attribute(text({ name: "content", label: "Content" }).multiline()).attribute(
4735
+ ).attribute(richtext({ name: "content", label: "Content" })).attribute(
4521
4736
  select({ name: "kind", label: "Kind" }).options([
4522
4737
  { value: "fact", label: "Fact" },
4523
4738
  { value: "preference", label: "Preference" },
4524
4739
  { value: "feedback", label: "Feedback" },
4525
4740
  { value: "reference", label: "Reference" }
4526
4741
  ])
4527
- ).attribute(relation({ name: "subjects", label: "Subjects" }).toAny().many()).attribute(relation({ name: "links", label: "Links" }).to("memory").many()).build();
4528
- var MEMORY_VIEW = detailView("memory-detail", "Memory").for("memory").default().sidePanel({ attributes: ["name", "description", "kind", "subjects", "links"] }).tab("content", "Content").form(group("content", "Content").field("content", { span: 12 })).build();
4529
- var MEMORY_LIST_VIEW = listView("memory-list", "Memories").for("memory").default().tab("workspace", "Memories").default().icon("table").visibility("workspace").table().columns("name", "kind", "description", "createdAt").sort("name", "asc").tab("mine", "Mes m\xE9moires").icon("lock").visibility("private").table().columns("name", "kind", "description", "createdAt").sort("name", "asc").build();
4742
+ ).attribute(relation({ name: "subjects", label: "Subjects" }).toAny().many()).attribute(relation({ name: "links", label: "Links" }).to("memory").many()).attribute(
4743
+ select({ name: "source", label: "Source" }).options([
4744
+ { value: "explicit", label: "Saved by an agent" },
4745
+ { value: "extracted", label: "Extracted from a session" },
4746
+ { value: "corroborated", label: "Corroborated across users" }
4747
+ ])
4748
+ ).attribute(date({ name: "validFrom", label: "Valid from" }).includeTime()).attribute(date({ name: "invalidAt", label: "Invalid at" }).includeTime()).attribute(relation({ name: "supersededBy", label: "Superseded by" }).to("memory")).build();
4749
+ var MEMORY_VIEW = detailView("memory-detail", "Memory").for("memory").default().sidePanel({
4750
+ attributes: [
4751
+ "description",
4752
+ "kind",
4753
+ "source",
4754
+ "validFrom",
4755
+ "invalidAt",
4756
+ "supersededBy",
4757
+ "subjects",
4758
+ "links"
4759
+ ]
4760
+ }).tab("content", "Content").richtext("content").titleAttribute("name").build();
4761
+ 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();
4530
4762
 
4531
4763
  // src/views/registry.ts
4532
4764
  function cloneViewDefinition(view) {
@@ -4935,6 +5167,65 @@ var FormRegistry = class {
4935
5167
  };
4936
5168
  var formRegistry = new FormRegistry();
4937
5169
 
5170
+ // src/realtime/agent-ui-message-batch.ts
5171
+ var AGENT_UI_BATCH_MAX_BYTES = 204800;
5172
+ var AGENT_UI_BATCH_MAX_ITEMS = 256;
5173
+ function isRecord(value) {
5174
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5175
+ }
5176
+ function hasExactKeys(value, allowed) {
5177
+ const keys = Object.keys(value);
5178
+ return keys.length === allowed.length && keys.every((key) => allowed.includes(key));
5179
+ }
5180
+ function isPositiveInteger(value) {
5181
+ return typeof value === "number" && Number.isInteger(value) && value > 0;
5182
+ }
5183
+ function isNonNegativeInteger(value) {
5184
+ return typeof value === "number" && Number.isInteger(value) && value >= 0;
5185
+ }
5186
+ function isContentRange(value) {
5187
+ if (!(isRecord(value) && hasExactKeys(value, ["kind", "startOffset", "endOffset"]))) {
5188
+ return false;
5189
+ }
5190
+ return (value.kind === "text" || value.kind === "reasoning") && isNonNegativeInteger(value.startOffset) && isNonNegativeInteger(value.endOffset) && value.endOffset >= value.startOffset;
5191
+ }
5192
+ function isBatchItem(value) {
5193
+ if (!isRecord(value)) return false;
5194
+ const expectedKeys = value.content === void 0 ? ["sequence", "chunk"] : ["sequence", "content", "chunk"];
5195
+ return hasExactKeys(value, expectedKeys) && isPositiveInteger(value.sequence) && value.chunk !== void 0 && (value.content === void 0 || isContentRange(value.content));
5196
+ }
5197
+ function encodedSize(value) {
5198
+ try {
5199
+ return new TextEncoder().encode(JSON.stringify(value)).byteLength;
5200
+ } catch {
5201
+ return void 0;
5202
+ }
5203
+ }
5204
+ function isAgentUIMessageBatch(value) {
5205
+ if (!(isRecord(value) && hasExactKeys(value, [
5206
+ "schemaVersion",
5207
+ "batchId",
5208
+ "tenantId",
5209
+ "sessionId",
5210
+ "streamId",
5211
+ "sequenceStart",
5212
+ "sequenceEnd",
5213
+ "items"
5214
+ ])) || value.schemaVersion !== 1 || typeof value.batchId !== "string" || value.batchId.trim() === "" || typeof value.tenantId !== "string" || value.tenantId.trim() === "" || typeof value.sessionId !== "string" || value.sessionId.trim() === "" || typeof value.streamId !== "string" || value.streamId.trim() === "" || !isPositiveInteger(value.sequenceStart) || !isPositiveInteger(value.sequenceEnd) || !Array.isArray(value.items) || value.items.length === 0 || value.items.length > AGENT_UI_BATCH_MAX_ITEMS || !value.items.every(isBatchItem)) {
5215
+ return false;
5216
+ }
5217
+ let previous = 0;
5218
+ for (const item of value.items) {
5219
+ if (item.sequence <= previous) return false;
5220
+ previous = item.sequence;
5221
+ }
5222
+ if (value.items[0]?.sequence !== value.sequenceStart || value.items.at(-1)?.sequence !== value.sequenceEnd) {
5223
+ return false;
5224
+ }
5225
+ const size = encodedSize(value);
5226
+ return size !== void 0 && size <= AGENT_UI_BATCH_MAX_BYTES;
5227
+ }
5228
+
4938
5229
  // src/realtime/channels.ts
4939
5230
  function liveChannelKey(channel) {
4940
5231
  switch (channel.kind) {
@@ -5000,47 +5291,6 @@ function parseLiveChannelKey(key) {
5000
5291
  return null;
5001
5292
  }
5002
5293
 
5003
- // src/realtime/cursors.ts
5004
- var LIVE_STREAM_START_CURSOR = "0-0";
5005
- var LIVE_STREAM_CURSOR_PATTERN = /^(0|[1-9]\d*)-(0|[1-9]\d*)$/;
5006
- function parseLiveStreamCursor(cursor) {
5007
- if (!LIVE_STREAM_CURSOR_PATTERN.test(cursor)) {
5008
- return null;
5009
- }
5010
- const [milliseconds = "0", sequence = "0"] = cursor.split("-");
5011
- return [BigInt(milliseconds), BigInt(sequence)];
5012
- }
5013
- function isLiveStreamCursor(value) {
5014
- return typeof value === "string" && parseLiveStreamCursor(value) !== null;
5015
- }
5016
- function assertLiveStreamCursor(cursor, label = "cursor") {
5017
- if (cursor === null) {
5018
- return;
5019
- }
5020
- if (!isLiveStreamCursor(cursor)) {
5021
- throw new Error(`Invalid live stream cursor for ${label}: ${cursor}`);
5022
- }
5023
- }
5024
- function compareLiveStreamCursors(left, right) {
5025
- const leftCursor = parseLiveStreamCursor(left);
5026
- if (!leftCursor) {
5027
- throw new Error(`Invalid live stream cursor for left: ${left}`);
5028
- }
5029
- const rightCursor = parseLiveStreamCursor(right);
5030
- if (!rightCursor) {
5031
- throw new Error(`Invalid live stream cursor for right: ${right}`);
5032
- }
5033
- const [leftMilliseconds, leftSequence] = leftCursor;
5034
- const [rightMilliseconds, rightSequence] = rightCursor;
5035
- if (leftMilliseconds !== rightMilliseconds) {
5036
- return leftMilliseconds < rightMilliseconds ? -1 : 1;
5037
- }
5038
- if (leftSequence !== rightSequence) {
5039
- return leftSequence < rightSequence ? -1 : 1;
5040
- }
5041
- return 0;
5042
- }
5043
-
5044
5294
  // src/realtime/events.ts
5045
5295
  var BROWSER_PREVIEW_STATUSES = ["live", "paused", "ended", "disconnected"];
5046
5296
  var LIVE_EVENT_TYPE_REGISTRY = {
@@ -5125,13 +5375,13 @@ function isLiveEventType(value) {
5125
5375
  return typeof value === "string" && LIVE_EVENT_TYPES.includes(value);
5126
5376
  }
5127
5377
  function isLiveEventPayload(payload) {
5128
- if (!(isRecord(payload) && isLiveEventType(payload.type))) {
5378
+ if (!(isRecord2(payload) && isLiveEventType(payload.type))) {
5129
5379
  return false;
5130
5380
  }
5131
5381
  return isLiveEventPayloadForType(payload.type, payload);
5132
5382
  }
5133
5383
  function isLiveEventPayloadForType(type, payload) {
5134
- if (!isRecord(payload)) {
5384
+ if (!isRecord2(payload)) {
5135
5385
  return false;
5136
5386
  }
5137
5387
  switch (type) {
@@ -5165,7 +5415,7 @@ function isLiveEventPayloadForType(type, payload) {
5165
5415
  return false;
5166
5416
  }
5167
5417
  }
5168
- function isRecord(value) {
5418
+ function isRecord2(value) {
5169
5419
  return typeof value === "object" && value !== null && !Array.isArray(value);
5170
5420
  }
5171
5421
  function isString(value) {
@@ -5227,13 +5477,13 @@ function isNotificationWorkState(value) {
5227
5477
  return isOneOf(value, NOTIFICATION_WORK_STATES);
5228
5478
  }
5229
5479
  function isNotificationSubject(value) {
5230
- return isRecord(value) && hasString(value, "type") && hasString(value, "id");
5480
+ return isRecord2(value) && hasString(value, "type") && hasString(value, "id");
5231
5481
  }
5232
5482
  function isRecordFieldPatch(value) {
5233
- return isRecord(value) && hasString(value, "fieldKey") && Object.hasOwn(value, "value") && hasVersion(value, "version");
5483
+ return isRecord2(value) && hasString(value, "fieldKey") && Object.hasOwn(value, "value") && hasVersion(value, "version");
5234
5484
  }
5235
5485
  function isRecordPatchPayload(payload) {
5236
- return payload.type === "record.patch" && hasString(payload, "objectId") && hasString(payload, "recordId") && hasVersion(payload, "recordVersion") && hasOptional(payload, "label", isString) && hasOptional(payload, "metadata", isRecord) && Array.isArray(payload.fieldPatches) && payload.fieldPatches.every(isRecordFieldPatch) && hasString(payload, "updatedAt");
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");
5237
5487
  }
5238
5488
  function isRecordDeletedPayload(payload) {
5239
5489
  return payload.type === "record.deleted" && hasString(payload, "objectId") && hasString(payload, "recordId") && hasVersion(payload, "recordVersion") && hasString(payload, "deletedAt");
@@ -5242,7 +5492,7 @@ function isRecordRemovedPayload(payload) {
5242
5492
  return payload.type === "record.removed" && hasOnlyKeys(payload, RECORD_REMOVED_PAYLOAD_KEYS) && hasString(payload, "objectId") && hasString(payload, "recordId") && hasVersion(payload, "recordVersion");
5243
5493
  }
5244
5494
  function isRecordLiveSnapshot(value) {
5245
- return isRecord(value) && hasOnlyKeys(value, RECORD_LIVE_SNAPSHOT_KEYS) && hasString(value, "id") && hasString(value, "objectId") && isOneOf(value.visibility, ["workspace", "private"]) && isNullableString(value.ownedBy) && (value.visibility === "workspace" && value.ownedBy === null || value.visibility === "private" && isNonEmptyString(value.ownedBy)) && hasString(value, "label") && isRecord(value.values) && hasOptional(value, "metadata", isRecord) && hasIsoDateString(value, "createdAt") && hasIsoDateString(value, "updatedAt") && hasOptional(value, "createdBy", isString) && hasOptional(value, "lastUpdatedBy", isString) && hasVersion(value, "schemaVersion");
5495
+ return isRecord2(value) && hasOnlyKeys(value, RECORD_LIVE_SNAPSHOT_KEYS) && hasString(value, "id") && hasString(value, "objectId") && isOneOf(value.visibility, ["workspace", "private"]) && isNullableString(value.ownedBy) && (value.visibility === "workspace" && value.ownedBy === null || value.visibility === "private" && isNonEmptyString(value.ownedBy)) && hasString(value, "label") && isRecord2(value.values) && hasOptional(value, "metadata", isRecord2) && hasIsoDateString(value, "createdAt") && hasIsoDateString(value, "updatedAt") && hasOptional(value, "createdBy", isString) && hasOptional(value, "lastUpdatedBy", isString) && hasVersion(value, "schemaVersion");
5246
5496
  }
5247
5497
  function isRecordCreatedPayload(payload) {
5248
5498
  return payload.type === "record.created" && hasOnlyKeys(payload, RECORD_CREATED_PAYLOAD_KEYS) && hasString(payload, "objectId") && hasString(payload, "recordId") && hasVersion(payload, "recordVersion") && isRecordLiveSnapshot(payload.record) && payload.record.id === payload.recordId && payload.record.objectId === payload.objectId;
@@ -5251,19 +5501,19 @@ function isViewProjectionStalePayload(payload) {
5251
5501
  return payload.type === "view.projection.stale" && hasString(payload, "viewId") && isOneOf(payload.reason, VIEW_PROJECTION_STALE_REASONS);
5252
5502
  }
5253
5503
  function isAgentSessionPatchPayload(payload) {
5254
- return payload.type === "agent.session.patch" && hasString(payload, "sessionId") && isRecord(payload.patch) && hasVersion(payload, "version") && hasString(payload, "updatedAt");
5504
+ return payload.type === "agent.session.patch" && hasString(payload, "sessionId") && isRecord2(payload.patch) && hasVersion(payload, "version") && hasString(payload, "updatedAt");
5255
5505
  }
5256
5506
  function isAgentUnreadPatchPayload(payload) {
5257
- return payload.type === "agent.unread.patch" && hasString(payload, "targetActorId") && hasString(payload, "sessionId") && hasVersion(payload, "unreadCount") && hasVersion(payload, "version") && hasString(payload, "updatedAt") && (!Object.hasOwn(payload, "session") || isRecord(payload.session) && payload.session.id === payload.sessionId);
5507
+ return payload.type === "agent.unread.patch" && hasString(payload, "targetActorId") && hasString(payload, "sessionId") && hasVersion(payload, "unreadCount") && hasVersion(payload, "version") && hasString(payload, "updatedAt") && (!Object.hasOwn(payload, "session") || isRecord2(payload.session) && payload.session.id === payload.sessionId);
5258
5508
  }
5259
5509
  function isLiveNotification(value) {
5260
- return isRecord(value) && hasString(value, "id") && hasString(value, "tenantId") && hasOptional(value, "senderActorId", isString) && hasOptional(value, "rootActorId", isString) && hasOptional(value, "triggeredByActorId", isString) && isNotificationKind(value.kind) && hasString(value, "type") && hasOptional(value, "subject", isNotificationSubject) && hasString(value, "title") && hasOptional(value, "summary", isString) && isRecord(value.payload) && isNotificationPriority(value.priority) && isNotificationSensitivity(value.sensitivity) && hasOptional(value, "threadKey", isString) && hasOptional(value, "idempotencyKey", isString) && hasOptional(value, "expiresAt", isIsoDateString) && hasIsoDateString(value, "createdAt") && hasIsoDateString(value, "updatedAt");
5510
+ return isRecord2(value) && hasString(value, "id") && hasString(value, "tenantId") && hasOptional(value, "senderActorId", isString) && hasOptional(value, "rootActorId", isString) && hasOptional(value, "triggeredByActorId", isString) && isNotificationKind(value.kind) && hasString(value, "type") && hasOptional(value, "subject", isNotificationSubject) && hasString(value, "title") && hasOptional(value, "summary", isString) && isRecord2(value.payload) && isNotificationPriority(value.priority) && isNotificationSensitivity(value.sensitivity) && hasOptional(value, "threadKey", isString) && hasOptional(value, "idempotencyKey", isString) && hasOptional(value, "expiresAt", isIsoDateString) && hasIsoDateString(value, "createdAt") && hasIsoDateString(value, "updatedAt");
5261
5511
  }
5262
5512
  function isLiveNotificationRecipient(value) {
5263
- return isRecord(value) && hasString(value, "id") && hasString(value, "tenantId") && hasString(value, "notificationId") && hasString(value, "recipientActorId") && isNotificationInboxState(value.inboxState) && isNotificationWorkState(value.workState) && hasOptional(value, "lockedAt", isIsoDateString) && hasOptional(value, "lockedByActorId", isString) && hasOptional(value, "readAt", isIsoDateString) && hasOptional(value, "archivedAt", isIsoDateString) && hasOptional(value, "snoozedUntil", isIsoDateString) && hasOptional(value, "completedAt", isIsoDateString) && hasOptional(value, "dismissedAt", isIsoDateString) && hasIsoDateString(value, "createdAt") && hasIsoDateString(value, "updatedAt");
5513
+ return isRecord2(value) && hasString(value, "id") && hasString(value, "tenantId") && hasString(value, "notificationId") && hasString(value, "recipientActorId") && isNotificationInboxState(value.inboxState) && isNotificationWorkState(value.workState) && hasOptional(value, "lockedAt", isIsoDateString) && hasOptional(value, "lockedByActorId", isString) && hasOptional(value, "readAt", isIsoDateString) && hasOptional(value, "archivedAt", isIsoDateString) && hasOptional(value, "snoozedUntil", isIsoDateString) && hasOptional(value, "completedAt", isIsoDateString) && hasOptional(value, "dismissedAt", isIsoDateString) && hasIsoDateString(value, "createdAt") && hasIsoDateString(value, "updatedAt");
5264
5514
  }
5265
5515
  function isNotificationRecipientPatch(value) {
5266
- if (!isRecord(value)) {
5516
+ if (!isRecord2(value)) {
5267
5517
  return false;
5268
5518
  }
5269
5519
  return Object.keys(value).every(
@@ -5287,14 +5537,14 @@ function isConversationRenamedPayload(payload) {
5287
5537
  }
5288
5538
  function isBrowserPreviewUpdatedPayload(payload) {
5289
5539
  const preview = payload.preview;
5290
- return payload.type === "browser.preview.updated" && hasOnlyKeys(payload, BROWSER_PREVIEW_UPDATED_PAYLOAD_KEYS) && isRecord(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}`;
5540
+ 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}`;
5291
5541
  }
5292
5542
  function isChannelRevokedPayload(payload) {
5293
5543
  return payload.type === "channel.revoked" && hasString(payload, "channel") && isOneOf(payload.reason, CHANNEL_REVOKED_REASONS);
5294
5544
  }
5295
5545
 
5296
5546
  // src/realtime/protocol.ts
5297
- function isRecord2(value) {
5547
+ function isRecord3(value) {
5298
5548
  return typeof value === "object" && value !== null && !Array.isArray(value);
5299
5549
  }
5300
5550
  function payloadChannel(payload) {
@@ -5302,46 +5552,11 @@ function payloadChannel(payload) {
5302
5552
  return typeof channel === "string" && parseLiveChannelKey(channel) ? channel : null;
5303
5553
  }
5304
5554
  function getLiveProtocolPayloadChannel(payload) {
5305
- return isRecord2(payload) ? payloadChannel(payload) : null;
5555
+ return isRecord3(payload) ? payloadChannel(payload) : null;
5306
5556
  }
5307
5557
  function isLiveEventEnvelope(payload) {
5308
- if (!isRecord2(payload)) return false;
5309
- return typeof payload.id === "string" && isLiveStreamCursor(payload.id) && typeof payload.channel === "string" && typeof payload.type === "string" && typeof payload.tenantId === "string" && payload.tenantId.length > 0 && typeof payload.occurredAt === "string" && isRecord2(payload.payload);
5310
- }
5311
- function parseLiveSubscribePayload(payload) {
5312
- if (!isRecord2(payload)) return null;
5313
- const channel = payloadChannel(payload);
5314
- if (!channel) return null;
5315
- const { cursor } = payload;
5316
- if (cursor !== void 0 && cursor !== null) {
5317
- if (typeof cursor !== "string" || !isLiveStreamCursor(cursor)) {
5318
- return null;
5319
- }
5320
- }
5321
- return { channel, cursor: cursor ?? null };
5322
- }
5323
- function parseLiveUnsubscribePayload(payload) {
5324
- if (payload === void 0 || payload === null) return {};
5325
- if (!isRecord2(payload)) return null;
5326
- if (!Object.hasOwn(payload, "channel")) {
5327
- return {};
5328
- }
5329
- const channel = payloadChannel(payload);
5330
- return channel ? { channel } : null;
5331
- }
5332
- function isLiveReplayCompletePayload(payload) {
5333
- if (!isRecord2(payload)) return false;
5334
- const channel = payloadChannel(payload);
5335
- if (!channel) return false;
5336
- return payload.cursor === null || typeof payload.cursor === "string" && isLiveStreamCursor(payload.cursor);
5337
- }
5338
- function isLiveGapPayload(payload) {
5339
- if (!isRecord2(payload)) return false;
5340
- return payloadChannel(payload) !== null;
5341
- }
5342
- function isLiveErrorPayload(payload) {
5343
- if (!isRecord2(payload)) return false;
5344
- return payloadChannel(payload) !== null;
5558
+ if (!isRecord3(payload)) return false;
5559
+ return typeof payload.id === "string" && payload.id.length > 0 && typeof payload.channel === "string" && typeof payload.type === "string" && typeof payload.tenantId === "string" && payload.tenantId.length > 0 && typeof payload.occurredAt === "string" && isRecord3(payload.payload);
5345
5560
  }
5346
5561
 
5347
5562
  // src/computed/functions.ts
@@ -6127,14 +6342,14 @@ function resolvePathPart(value, part) {
6127
6342
  if (Array.isArray(value)) {
6128
6343
  return value.map((item) => resolvePathPart(item, part));
6129
6344
  }
6130
- if (!isPlainRecord(value)) {
6345
+ if (!isPlainRecord2(value)) {
6131
6346
  return null;
6132
6347
  }
6133
6348
  if (Object.hasOwn(value, part)) {
6134
6349
  return value[part] ?? null;
6135
6350
  }
6136
6351
  const nestedValues = value.values;
6137
- if (isPlainRecord(nestedValues) && Object.hasOwn(nestedValues, part)) {
6352
+ if (isPlainRecord2(nestedValues) && Object.hasOwn(nestedValues, part)) {
6138
6353
  return nestedValues[part] ?? null;
6139
6354
  }
6140
6355
  return null;
@@ -6236,9 +6451,9 @@ function evaluateCall(functionName, args) {
6236
6451
  case "percent_not_empty":
6237
6452
  return percentByEmptyState(args[0], false);
6238
6453
  case "count_empty":
6239
- return collectionItems(args[0]).filter(isEmptyValue).length;
6454
+ return collectionItems(args[0]).filter(isNullishOrEmptyString).length;
6240
6455
  case "count_not_empty":
6241
- return collectionItems(args[0]).filter((item) => !isEmptyValue(item)).length;
6456
+ return collectionItems(args[0]).filter((item) => !isNullishOrEmptyString(item)).length;
6242
6457
  case "count_unique":
6243
6458
  return uniqueNonEmpty(collectionItems(args[0])).length;
6244
6459
  default:
@@ -6281,14 +6496,14 @@ function percentByEmptyState(value, countEmpty) {
6281
6496
  if (items.length === 0) {
6282
6497
  return 0;
6283
6498
  }
6284
- const count = items.filter((item) => isEmptyValue(item) === countEmpty).length;
6499
+ const count = items.filter((item) => isNullishOrEmptyString(item) === countEmpty).length;
6285
6500
  return count / items.length;
6286
6501
  }
6287
6502
  function uniqueNonEmpty(values) {
6288
6503
  const seen = /* @__PURE__ */ new Set();
6289
6504
  const result = [];
6290
6505
  for (const value of values) {
6291
- if (isEmptyValue(value)) {
6506
+ if (isNullishOrEmptyString(value)) {
6292
6507
  continue;
6293
6508
  }
6294
6509
  const key = uniqueKey(value);
@@ -6309,9 +6524,6 @@ function collectionItems(value) {
6309
6524
  function flatten(values) {
6310
6525
  return values.flat(Number.POSITIVE_INFINITY);
6311
6526
  }
6312
- function isEmptyValue(value) {
6313
- return value === null || value === void 0 || value === "";
6314
- }
6315
6527
  function toFiniteNumber(value) {
6316
6528
  if (typeof value === "number") {
6317
6529
  return Number.isFinite(value) ? value : null;
@@ -6320,14 +6532,23 @@ function toFiniteNumber(value) {
6320
6532
  const parsed = Number(value);
6321
6533
  return Number.isFinite(parsed) ? parsed : null;
6322
6534
  }
6535
+ if (isCurrencyValue(value)) {
6536
+ return Number.isFinite(value.value) ? value.value : null;
6537
+ }
6323
6538
  return null;
6324
6539
  }
6540
+ function isCurrencyValue(value) {
6541
+ return typeof value === "object" && value !== null && typeof value.value === "number" && typeof value.code === "string";
6542
+ }
6325
6543
  function toDate(value) {
6326
6544
  if (value instanceof Date) {
6327
6545
  return Number.isNaN(value.getTime()) ? null : value;
6328
6546
  }
6329
6547
  if (typeof value !== "string") {
6330
- return null;
6548
+ const start = dateValueStart(value);
6549
+ if (start === null) return null;
6550
+ const ranged = new Date(start);
6551
+ return Number.isNaN(ranged.getTime()) ? null : ranged;
6331
6552
  }
6332
6553
  const date2 = new Date(value);
6333
6554
  return Number.isNaN(date2.getTime()) ? null : date2;
@@ -6342,7 +6563,7 @@ function uniqueKey(value) {
6342
6563
  }
6343
6564
  return `${typeof value}:${JSON.stringify(value)}`;
6344
6565
  }
6345
- function isPlainRecord(value) {
6566
+ function isPlainRecord2(value) {
6346
6567
  return typeof value === "object" && value !== null && !Array.isArray(value);
6347
6568
  }
6348
6569
  function formatComputedResult(value, returnType, decimals) {
@@ -6525,10 +6746,10 @@ var COMPUTED_FUNCTION_METADATA = [
6525
6746
  ];
6526
6747
 
6527
6748
  // src/filters/operators.ts
6528
- var isEmpty = (v) => v === null || v === void 0 || v === "" || Array.isArray(v) && v.length === 0;
6749
+ var isEmpty = (v) => isNullishOrEmptyString(v) || Array.isArray(v) && v.length === 0;
6529
6750
  var toStr = (v) => v == null ? "" : String(v);
6530
6751
  var toNum = (v) => {
6531
- if (v == null || v === "") return null;
6752
+ if (isNullishOrEmptyString(v)) return null;
6532
6753
  const n = typeof v === "number" ? v : Number(v);
6533
6754
  return Number.isFinite(n) ? n : null;
6534
6755
  };
@@ -6694,50 +6915,6 @@ var OPERATOR_SPECS = {
6694
6915
  }
6695
6916
  };
6696
6917
 
6697
- // src/filters/extract-filter-value.ts
6698
- function extractCurrencyFilterValue(value) {
6699
- if (typeof value === "number") return value;
6700
- if (value !== null && typeof value === "object" && "value" in value) {
6701
- const inner = value.value;
6702
- return typeof inner === "number" ? inner : null;
6703
- }
6704
- return null;
6705
- }
6706
- function extractFilterValue(value) {
6707
- if (value === null || value === void 0) return null;
6708
- if (typeof value === "object" && "value" in value) {
6709
- return value.value ?? null;
6710
- }
6711
- return value;
6712
- }
6713
-
6714
- // src/filters/polarity.ts
6715
- var NEGATIVE_OPERATORS = /* @__PURE__ */ new Set([
6716
- "is_not",
6717
- "not_contains",
6718
- "none_of",
6719
- "is_empty"
6720
- ]);
6721
- var NEGATIVE_TO_POSITIVE = {
6722
- is_not: "is",
6723
- not_contains: "contains",
6724
- none_of: "any_of",
6725
- is_empty: "is_not_empty"
6726
- };
6727
- function getOperatorPolarity(op) {
6728
- return NEGATIVE_OPERATORS.has(op) ? "none" : "any";
6729
- }
6730
- function normalizeForEdgeRpc(op) {
6731
- return NEGATIVE_TO_POSITIVE[op] ?? op;
6732
- }
6733
- var SINGLE_TO_MULTI = {
6734
- is: "any_of",
6735
- is_not: "none_of"
6736
- };
6737
- function toMultiValueOperator(op) {
6738
- return SINGLE_TO_MULTI[op] ?? op;
6739
- }
6740
-
6741
6918
  // src/filters/evaluate.ts
6742
6919
  var systemAttribute = (name, type) => ({ id: `system:${name}`, name, label: name, type, system: true });
6743
6920
  var RECORD_SYSTEM_ATTRIBUTES = [
@@ -6827,7 +7004,8 @@ function normalizeOperatorComparands(type, operator, storedValue, ruleValue) {
6827
7004
  if (type === "phone") return normalizePhoneComparands(storedValue, ruleValue);
6828
7005
  return [normalizeComparableValue(type, storedValue), normalizeComparableValue(type, ruleValue)];
6829
7006
  }
6830
- function normalizeUtcCalendarDay(value) {
7007
+ function normalizeUtcCalendarDay(raw) {
7008
+ const value = isDateRangeValue(raw) ? dateValueStart(raw) : raw;
6831
7009
  if (value instanceof Date)
6832
7010
  return Number.isNaN(value.getTime()) ? null : value.toISOString().slice(0, 10);
6833
7011
  if (typeof value !== "string" || value === "") return null;
@@ -6850,6 +7028,7 @@ function normalizePhoneComparands(stored, rule) {
6850
7028
  function normalizeComparableValue(type, value) {
6851
7029
  if (type === "currency") return extractCurrencyFilterValue(value);
6852
7030
  if (type === "date") {
7031
+ if (isDateRangeValue(value)) return dateValueStart(value);
6853
7032
  if (value instanceof Date) return Number.isNaN(value.getTime()) ? null : value.toISOString();
6854
7033
  return value;
6855
7034
  }
@@ -6918,6 +7097,20 @@ function resolveAttributeDefaultValue(attribute, ctx) {
6918
7097
  return attribute.includeTime ? ctx.now.toISOString() : dateInTimezone(ctx.now, ctx.timezone);
6919
7098
  }
6920
7099
 
7100
+ // src/utils/agent-title.ts
7101
+ var AGENT_FALLBACK_TITLE_MAX_LENGTH = 60;
7102
+ var STORAGE_PLACEHOLDER_TITLE = /^Session \d+$/;
7103
+ function buildAgentFallbackTitle(message) {
7104
+ const normalized = message.replace(/\s+/g, " ").trim().replace(/[.!?]+$/, "");
7105
+ if (!normalized) return "New conversation";
7106
+ return normalized.length > AGENT_FALLBACK_TITLE_MAX_LENGTH ? `${normalized.slice(0, AGENT_FALLBACK_TITLE_MAX_LENGTH - 1).trimEnd()}...` : normalized;
7107
+ }
7108
+ function conversationDisplayTitle(input) {
7109
+ const generated = input.generated?.trim();
7110
+ if (generated && !STORAGE_PLACEHOLDER_TITLE.test(generated)) return generated;
7111
+ return input.firstUserText ? buildAgentFallbackTitle(input.firstUserText) : input.emptyLabel;
7112
+ }
7113
+
6921
7114
  // src/utils/view-sync-payload.ts
6922
7115
  function viewSyncPayload(view) {
6923
7116
  return {
@@ -7100,7 +7293,7 @@ var destructiveSchema = z.object({
7100
7293
  )
7101
7294
  }).strict().default({ attributeRemovals: [], objectRemovals: [], renames: [] });
7102
7295
  var planSummarySchema = z.string().min(1).describe(
7103
- "One or two plain-language sentences describing the change and why, shown to the human who approves or rejects the plan \u2014 this is the only free-text context they see before deciding. If `destructive` is non-empty, say plainly what will be lost (e.g. 'deletes the \"ancienMontant\" column and its data on every devis'). Do not restate the raw plan \u2014 explain intent."
7296
+ "ONE sentence naming the intent of the change \u2014 what it is for, not what it contains. The human approving it has already watched every entry land in the preview window and can read every row of the plan itself, so a recap tells them nothing they do not have. A second sentence is warranted only when `destructive` is non-empty: say plainly what will be lost (e.g. 'deletes the \"ancienMontant\" column and its data on every devis'). Never restate the plan \u2014 explain intent."
7104
7297
  );
7105
7298
  var CANONICAL_CONFIG_DESCRIPTION = "The COMPLETE config this view should end up with \u2014 not a patch. Copy the baseline returned by get_default_view and edit it, preserving every tab and setting you are not changing: anything you omit is dropped. To change the columns shown, set `tabs[].columns` (an array of attribute names) \u2014 there is no top-level `columns` on either view type. For a detail view's side panel, set `sidePanel.attributes`. Every attribute name listed must already exist on the object, or be created earlier in this same plan. ONE EXCEPTION to omit-is-dropped: a tab with `type: \"custom\"` renders a component belonging to the application, which you cannot describe or recreate. Copy every such tab through from the baseline exactly as it came, `name`, `component` and `props` untouched \u2014 dropping one, inventing one, or altering any of those three is rejected rather than applied (`name` is the tab's address in links, not its wording). Its `label` and `icon` you may change.";
7106
7299
  var BASELINE_TOKEN_DESCRIPTION = "Opaque token returned by get_default_view alongside the baseline you edited. REQUIRED when the object already exists \u2014 it proves you authored against the baseline that is still current. Must be OMITTED when this plan creates the object, which has no baseline yet.";
@@ -7344,4 +7537,4 @@ var persistedSchemaPlanSchema = z.preprocess(
7344
7537
  structuralPersistedSchemaPlanSchema
7345
7538
  );
7346
7539
 
7347
- export { ALLOWED_PROPERTY_TYPES, ALL_ACTIONS, ALL_SYSTEM_RESOURCES, AUDIT_ACTIONS, AUDIT_RESOURCE_TYPES, ActivityTabConfig, AgentBuilder, BEHAVIOR_PROPERTIES, BROWSER_PREVIEW_STATUSES, BYTE_UNIT_LABELS, COMPUTED_FUNCTIONS, COMPUTED_FUNCTION_METADATA, COMPUTED_FUNCTION_NAMES, CONNECTOR_CALLBACK_PARAM, ComputedFormulaCompileError, CustomTabConfig, DB_COLUMN_FIELDS, DEFAULT_AGENT_EXECUTION_CONFIG, DEFAULT_APPROVAL_POLICY, DEFAULT_ROLES, DEFAULT_ROLE_DESCRIPTIONS, DEFAULT_ROLE_LABELS, DEFAULT_ROLE_PERMISSIONS, DOCUMENT_SYSTEM_ATTRIBUTES, DetailViewBuilder, DocumentsTabConfig, EMPTY_VALUE_PLACEHOLDER, ESTIMATED_COUNT_CAP, EmailsTabConfig, FORM_FORBIDDEN_ATTRIBUTE_TYPES, FlagRegistry, FlagService, FormBuilder, FormRegistry, FormRowBuilder, FormStepBuilder, GroupBuilder, IDENTITY_PROPERTIES, LIVE_EVENT_TYPES, LIVE_STREAM_START_CURSOR, ListViewBuilder, ListViewTabConfigBuilder, MAX_PRESET_DEPTH, MAX_TODOS, MAX_TODO_DESCRIPTION_CHARS, MAX_TODO_ID_CHARS, MAX_TODO_RESULT_CHARS, MEMORY_LIST_VIEW, MEMORY_OBJECT, MEMORY_VIEW, NOTIFICATION_INBOX_STATES, NOTIFICATION_KINDS, NOTIFICATION_PRIORITIES, NOTIFICATION_SENSITIVITIES, NOTIFICATION_TYPES_V1, NOTIFICATION_TYPE_AGENT_QUESTION_REQUESTED, NOTIFICATION_TYPE_AGENT_SESSION_COMPLETED, NOTIFICATION_TYPE_AGENT_SESSION_FAILED, NOTIFICATION_TYPE_AGENT_SESSION_TIMEOUT, NOTIFICATION_TYPE_AGENT_SESSION_WAITING_HUMAN, NOTIFICATION_TYPE_AGENT_TASK_ASSIGNED, NOTIFICATION_WORK_STATES, NoopGeocodingAdapter, OPERATOR_SPECS, ObjectBuilder, PRESENTATION_PROPERTIES, QUALIFIED_SEPARATOR, RECORD_CREATOR_ROOT_ACTOR_METADATA_KEY, RELATION_TARGET_ANY, RelationGroupBuilder, RichtextTabConfig, SCHEMA_PLAN_LIMITS, SESSION_TERMINAL_STATUSES, SKILL_LIST_VIEW, SKILL_OBJECT, SKILL_VIEW, STANDARD_SCHEMA_VENDOR, SYSTEM_RESOURCES, SYSTEM_RESOURCE_LABELS, TODAY_DEFAULT, TODO_PLAN_STATUSES, TODO_STATUSES, TabBuilder, TableTabConfig, USER_STATUSES, accessLevelToActions, actionsToAccessLevel, agent, agentDisplayName, applyPipes, applyRelationProps, assertAcyclicComputedDependencies, assertLiveStreamCursor, booleanFlag, buildPropertySchema, buildQualifiedAttribute, canonicalStringify, checkbox, compareLiveStreamCursors, compileComputedFormula, compileRollupAttribute, computeByteMagnitude, createFlagRegistry, createFlagService, createStandardSchemaProps, currency, date, dateInTimezone, dateValueStart, destructiveSchema, detailView, document, evaluateComputedAst, evaluateComputedFormula, evaluateComputedFormulaWithResult, evaluateFilterState, evaluateRecordFilterState, extractAttributeNames, extractCurrencyFilterValue, extractFilterValue, extractValueRefs, flagRegistry, form, formRegistry, formatAttributeValue, formatByteSize, formatComputedResult, formatLocationValue, formula, generateDefaultDetailView, generateDefaultListView, getActiveTab, getErrorMessage, getLiveProtocolPayloadChannel, getOperatorPolarity, getRecordCreatorPrincipalId, getSlotFieldTargets, getUserDisplayName, group, hasDestructiveEntries, hasOptions, inferInverseCardinality, inferRollupReturnType, isAttributeSortable2 as isAttributeSortable, isBilateralRelation, isCheckboxEquality, isComputedFunctionName, isDateRangeValue, isDefaultRole, isDetailView, isDocumentAttribute, isEmptyObject, isFieldGroup, isFormDefinition, isFormFieldsRow, isFormFreeFieldRef, isFormHeadingRow, isFormSeparatorRow, isFormSlotFieldRef, isFormTextRow, isLabelExpression, isListView, isLiveErrorPayload, isLiveEventEnvelope, isLiveEventPayload, isLiveEventPayloadForType, isLiveEventType, isLiveGapPayload, isLiveReplayCompletePayload, isLiveStreamCursor, isNotEmpty, isPlainRecord, isRelationGroup, isStandardSchema, isTerminalSessionStatus, isUniversalRelation, jsonFlag, listView, liveChannelKey, location, matchesAccepts, multiselect, normalizeDateValue, normalizeForEdgeRpc, number, numberFlag, object, parseLiveChannelKey, parseLiveSubscribePayload, parseLiveUnsubscribePayload, parseQualifiedAttribute, persistedDefaultViewTargetSchema, persistedSchemaPlanSchema, phone, plannedAttributeSchema, plannedInlineAttributeSchema, plannedObjectSchema, proposedDefaultViewTargetSchema, registry, relation, relationGroup, relationPropertyDefs, renderLabelExpression, resetViewToDefault, resolveAttributeDefaultValue, resolvePropertyDefinitions, richtext, rollup, rollupToFormulaExpression, schemaPlanSchema, select, status, stringFlag, text, toMultiValueOperator, toUndefinedIfEmpty, user, validateAttributeName, validateLabelExpression, validateObjectName, viewRegistry, viewStateKey, viewSyncPayload };
7540
+ 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, canonicalStringify, 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 };