@gravity-rail/sdk 0.22.0 → 0.32.0

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 (55) hide show
  1. package/README.md +57 -8
  2. package/dist/agui.d.cts +1 -1
  3. package/dist/agui.d.ts +1 -1
  4. package/dist/audio.d.cts +1 -1
  5. package/dist/audio.d.ts +1 -1
  6. package/dist/{client-C10qSd6b.d.ts → chat-interaction-BKdImgZ5.d.ts} +5604 -1531
  7. package/dist/{client-Ct0soeip.d.cts → chat-interaction-DLfC_h_P.d.cts} +5604 -1531
  8. package/dist/{chunk-3HAV5XUJ.js → chunk-HRUMZ46V.js} +1 -1
  9. package/dist/chunk-HRUMZ46V.js.map +1 -0
  10. package/dist/{chunk-WMA6YCAS.js → chunk-N446FGCT.js} +1230 -201
  11. package/dist/chunk-N446FGCT.js.map +1 -0
  12. package/dist/{chunk-7OLBLLV7.js → chunk-P2E6LU7I.js} +57 -7
  13. package/dist/chunk-P2E6LU7I.js.map +1 -0
  14. package/dist/helpers.cjs +54 -1
  15. package/dist/helpers.cjs.map +1 -1
  16. package/dist/helpers.d.cts +3 -2
  17. package/dist/helpers.d.ts +3 -2
  18. package/dist/helpers.js +11 -3
  19. package/dist/helpers.js.map +1 -1
  20. package/dist/index.cjs +2291 -148
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +509 -6
  23. package/dist/index.d.ts +509 -6
  24. package/dist/index.js +1032 -23
  25. package/dist/index.js.map +1 -1
  26. package/dist/internal.cjs +1320 -220
  27. package/dist/internal.cjs.map +1 -1
  28. package/dist/internal.d.cts +33 -49
  29. package/dist/internal.d.ts +33 -49
  30. package/dist/internal.js +73 -33
  31. package/dist/internal.js.map +1 -1
  32. package/dist/realtime.cjs +279 -14
  33. package/dist/realtime.cjs.map +1 -1
  34. package/dist/realtime.d.cts +169 -17
  35. package/dist/realtime.d.ts +169 -17
  36. package/dist/realtime.js +264 -13
  37. package/dist/realtime.js.map +1 -1
  38. package/dist/{revision-state-CCPTiW-i.d.cts → revision-state-Bsq5dKwi.d.cts} +236 -5
  39. package/dist/{revision-state-C6aM-PHu.d.ts → revision-state-CQTYcIRG.d.ts} +236 -5
  40. package/dist/schemas.cjs +3 -1
  41. package/dist/schemas.cjs.map +1 -1
  42. package/dist/schemas.d.cts +31 -13
  43. package/dist/schemas.d.ts +31 -13
  44. package/dist/schemas.js +4 -2
  45. package/dist/schemas.js.map +1 -1
  46. package/dist/{tasks-WH_VfzMv.d.cts → tasks-B-31JPuq.d.cts} +298 -114
  47. package/dist/{tasks-WH_VfzMv.d.ts → tasks-B-31JPuq.d.ts} +298 -114
  48. package/dist/types-0c6_NGU4.d.cts +90 -0
  49. package/dist/types-0c6_NGU4.d.ts +90 -0
  50. package/package.json +3 -3
  51. package/dist/chunk-3HAV5XUJ.js.map +0 -1
  52. package/dist/chunk-7OLBLLV7.js.map +0 -1
  53. package/dist/chunk-WMA6YCAS.js.map +0 -1
  54. package/dist/types-DkYyrvoC.d.cts +0 -19
  55. package/dist/types-DkYyrvoC.d.ts +0 -19
package/dist/index.cjs CHANGED
@@ -28,6 +28,16 @@ __export(src_exports, {
28
28
  AccessGrantStatus: () => AccessGrantStatus,
29
29
  AccessGrantTrigger: () => AccessGrantTrigger,
30
30
  AccessLevel: () => AccessLevel2,
31
+ ActivityCapability: () => ActivityCapability,
32
+ ActivityEventFamily: () => ActivityEventFamily,
33
+ ActivityEventType: () => ActivityEventType,
34
+ ActivityGrain: () => ActivityGrain,
35
+ ActivityGroupBy: () => ActivityGroupBy,
36
+ ActivityOpenItemOrder: () => ActivityOpenItemOrder,
37
+ ActivityOutcome: () => ActivityOutcome,
38
+ ActivityVisibility: () => ActivityVisibility,
39
+ ActivityWindowBasis: () => ActivityWindowBasis,
40
+ ActorKind: () => ActorKind,
31
41
  AgentBuilder: () => AgentBuilder,
32
42
  ApiError: () => ApiError,
33
43
  ApplyError: () => ApplyError,
@@ -48,8 +58,15 @@ __export(src_exports, {
48
58
  CalendarScheduleRecurrence: () => CalendarScheduleRecurrence,
49
59
  CalendarSource: () => CalendarSource,
50
60
  CapabilityClass: () => CapabilityClass,
61
+ ChannelMessageDirection: () => ChannelMessageDirection,
62
+ ChannelMessageSource: () => ChannelMessageSource,
63
+ ChannelMessagesUnavailableReason: () => ChannelMessagesUnavailableReason,
64
+ ChatInteractionController: () => ChatInteractionController,
51
65
  ConsentMethod: () => ConsentMethod,
52
66
  CriterionType: () => CriterionType,
67
+ DEFAULT_AGENT_CHAT_MODEL: () => DEFAULT_AGENT_CHAT_MODEL,
68
+ DEFAULT_AGENT_REALTIME_MODEL: () => DEFAULT_AGENT_REALTIME_MODEL,
69
+ DEFAULT_AGENT_REALTIME_MODEL_CONFIG: () => DEFAULT_AGENT_REALTIME_MODEL_CONFIG,
53
70
  DEFAULT_CHAT_MODEL: () => DEFAULT_CHAT_MODEL,
54
71
  DEFAULT_CUSTOM_VOICE_MODEL: () => DEFAULT_CUSTOM_VOICE_MODEL,
55
72
  DEFAULT_THINKING_SPEECH_PHRASES: () => DEFAULT_THINKING_SPEECH_PHRASES,
@@ -60,7 +77,9 @@ __export(src_exports, {
60
77
  DataSensitivity: () => DataSensitivity,
61
78
  DataTypeRecordScope: () => DataTypeRecordScope,
62
79
  DriverMode: () => DriverMode,
80
+ EhrWritebackOutcomeResponseStatus: () => EhrWritebackOutcomeResponseStatus,
63
81
  EmailDnsRecordType: () => EmailDnsRecordType,
82
+ EntityKind: () => EntityKind,
64
83
  EventRuleActionType: () => EventRuleActionType,
65
84
  EventRuleEventType: () => EventRuleEventType,
66
85
  EventRuleObjectType: () => EventRuleObjectType,
@@ -71,6 +90,11 @@ __export(src_exports, {
71
90
  FhirVendor: () => FhirVendor,
72
91
  FormBuilder: () => FormBuilder,
73
92
  GravityRailClient: () => GravityRailClient,
93
+ ImportSkippedRuleResourceGroupResourceType: () => ImportSkippedRuleResourceGroupResourceType,
94
+ ImportSkippedRuleResponseNeededResourceTypesItem: () => ImportSkippedRuleResponseNeededResourceTypesItem,
95
+ ImportSkippedRuleResponseParentKind: () => ImportSkippedRuleResponseParentKind,
96
+ ImportSkippedRuleResponseReasonCode: () => ImportSkippedRuleResponseReasonCode,
97
+ ImportSkippedRuleResponseStatus: () => ImportSkippedRuleResponseStatus,
74
98
  InboundFaxStatusValues: () => InboundFaxStatus,
75
99
  IndexStatus: () => IndexStatus,
76
100
  InvitationStatus: () => InvitationStatus,
@@ -78,6 +102,7 @@ __export(src_exports, {
78
102
  JourneyBuilder: () => JourneyBuilder,
79
103
  JourneyStepBuilder: () => JourneyStepBuilder,
80
104
  MASKED_SECRET_SENTINEL: () => MASKED_SECRET_SENTINEL,
105
+ MEMBER_RELATIONSHIP_KINDS: () => MEMBER_RELATIONSHIP_KINDS,
81
106
  McpServerState: () => McpServerState,
82
107
  MemberFeature: () => MemberFeature,
83
108
  MemberFilterBuilder: () => MemberFilterBuilder,
@@ -85,6 +110,7 @@ __export(src_exports, {
85
110
  MemberImportPreviewRowAction: () => MemberImportPreviewRowAction,
86
111
  MemberImportValidationError: () => MemberImportValidationError,
87
112
  MemberLabelBuilder: () => MemberLabelBuilder,
113
+ MemberRelationshipKind: () => MemberRelationshipKind,
88
114
  MemberType: () => MemberType,
89
115
  MenuItemResponseItemType: () => MenuItemResponseItemType,
90
116
  MenuItemType: () => MenuItemResponseItemType,
@@ -120,8 +146,11 @@ __export(src_exports, {
120
146
  REALTIME_MODEL_OPENAI: () => REALTIME_MODEL_OPENAI,
121
147
  REALTIME_MODEL_OPENAI_2: () => REALTIME_MODEL_OPENAI_2,
122
148
  REALTIME_MODEL_OPENAI_MINI: () => REALTIME_MODEL_OPENAI_MINI,
149
+ RefResolutionStatus: () => RefResolutionStatus,
123
150
  Region: () => Region,
124
151
  RegistrationIdentifier: () => RegistrationIdentifier,
152
+ RelatedMemberRole: () => RelatedMemberRole,
153
+ RelationshipCardinality: () => RelationshipCardinality,
125
154
  Resource: () => Resource,
126
155
  RoleUpdate: () => RoleUpdate,
127
156
  RoutineBuilder: () => RoutineBuilder,
@@ -146,7 +175,12 @@ __export(src_exports, {
146
175
  TTS_PREVIEW_PROVIDERS: () => TTS_PREVIEW_PROVIDERS,
147
176
  TaskBuilder: () => TaskBuilder,
148
177
  TemplatesApi: () => TemplatesApi,
178
+ TestChatRunLane: () => TestChatRunLane,
179
+ TestChatRunOutcome: () => TestChatRunOutcome,
149
180
  ToolkitState: () => ToolkitState,
181
+ UiPromptPresentedKindValues: () => UiPromptPresentedKind,
182
+ UiPromptResponseKindValues: () => UiPromptResponseKind,
183
+ UiPromptResponseStatusValues: () => UiPromptResponseStatus,
150
184
  WIDGET_SLUGS: () => WIDGET_SLUGS,
151
185
  WORKFLOW_IMPLICIT_USE_SCOPE: () => WORKFLOW_IMPLICIT_USE_SCOPE,
152
186
  WorkflowAccessWarningResourceType: () => WorkflowAccessWarningResourceType,
@@ -221,6 +255,9 @@ function isApiValidationError(value) {
221
255
  const v = value;
222
256
  return typeof v.field === "string" && typeof v.kind === "string" && typeof v.message === "string";
223
257
  }
258
+ function logApiClientError(_error) {
259
+ console.warn("API request failed");
260
+ }
224
261
  var ApiError = class extends Error {
225
262
  statusCode;
226
263
  /** Legacy string-array errors — kept for non-validation callers. */
@@ -239,6 +276,7 @@ var ApiError = class extends Error {
239
276
  errorData;
240
277
  constructor(message, statusCode, errors, validationErrors) {
241
278
  super(message);
279
+ this.name = "ApiError";
242
280
  this.statusCode = statusCode;
243
281
  this.errors = errors;
244
282
  this.validationErrors = validationErrors;
@@ -498,9 +536,10 @@ ${formattedErrors}`, response.status);
498
536
  const message = errorData.detail ? `${errorData.detail}: ${details}` : `Validation failed: ${details}`;
499
537
  throw new ApiError(message, response.status, stringErrors);
500
538
  }
501
- const structuredError = errorData.detail || errorData;
539
+ const detail = errorData.detail;
540
+ const structuredError = detail && typeof detail === "object" ? detail : errorData;
502
541
  if (structuredError && typeof structuredError === "object" && (structuredError.error === true || structuredError.code)) {
503
- const message = structuredError.message || structuredError.code || "Unknown error";
542
+ const message = typeof detail === "string" && detail || structuredError.message || structuredError.code || "Unknown error";
504
543
  const error = new ApiError(message, response.status);
505
544
  error.errorData = structuredError;
506
545
  throw error;
@@ -517,7 +556,7 @@ ${formattedErrors}`, response.status);
517
556
  }
518
557
  return response.json();
519
558
  } catch (error) {
520
- console.warn(error);
559
+ logApiClientError(error);
521
560
  throw error;
522
561
  }
523
562
  }
@@ -624,7 +663,7 @@ ${formattedErrors}`, response.status);
624
663
  }
625
664
  return response;
626
665
  } catch (error) {
627
- console.warn(error);
666
+ logApiClientError(error);
628
667
  throw error;
629
668
  }
630
669
  }
@@ -670,7 +709,7 @@ ${formattedErrors}`, response.status);
670
709
  }
671
710
  return response.json();
672
711
  } catch (error) {
673
- console.warn(error);
712
+ logApiClientError(error);
674
713
  throw error;
675
714
  }
676
715
  }
@@ -1911,17 +1950,6 @@ var CallsApi = class extends BaseApiClient {
1911
1950
  `w/${wid}/calls${params.toString() ? `?${params.toString()}` : ""}`
1912
1951
  );
1913
1952
  }
1914
- /** Initiate a new outbound call. */
1915
- async initiateCall(wid, request) {
1916
- return this.fetch(`w/${wid}/call`, {
1917
- method: "POST",
1918
- body: JSON.stringify(request)
1919
- });
1920
- }
1921
- /** Get a voice authentication token for real-time audio. */
1922
- async getVoiceToken(wid) {
1923
- return this.fetch(`w/${wid}/voice/token`);
1924
- }
1925
1953
  /** Get message timing data for a chat recording. */
1926
1954
  async getMessageTiming(wid, chatId) {
1927
1955
  return this.fetch(`w/${wid}/recordings/chat/${chatId}/message-timing`);
@@ -2047,6 +2075,26 @@ var ChatsApi = class extends BaseApiClient {
2047
2075
  async getChat(wid, id) {
2048
2076
  return this.fetch(`w/${wid}/chats/${id}`);
2049
2077
  }
2078
+ /**
2079
+ * Get a short-lived, interactive AgentCore browser view for this Chat.
2080
+ *
2081
+ * The signed URL is deliberately response-local. Callers must keep it in
2082
+ * memory only and request a fresh value when reopening the view.
2083
+ */
2084
+ async getChatBrowserLiveView(wid, chatId) {
2085
+ const response = await this.fetchRaw(`w/${wid}/chats/${chatId}/browser/live-view`);
2086
+ if (response.status === 204) return null;
2087
+ return response.json();
2088
+ }
2089
+ /**
2090
+ * Which machine resources this Chat is running right now.
2091
+ *
2092
+ * Infrastructure state only — no Chat content — so it is safe to poll while
2093
+ * a Chat is open.
2094
+ */
2095
+ async getChatMachineResources(wid, chatId) {
2096
+ return this.fetch(`w/${wid}/chats/${chatId}/machine-resources`);
2097
+ }
2050
2098
  /**
2051
2099
  * Create-chat preflight for SMS: is a conversation already live between this
2052
2100
  * workspace number and this member?
@@ -2074,6 +2122,23 @@ var ChatsApi = class extends BaseApiClient {
2074
2122
  async getChatCallbacks(wid, chatId) {
2075
2123
  return this.fetch(`w/${wid}/chats/${chatId}/callbacks`);
2076
2124
  }
2125
+ /**
2126
+ * List EHR write-back outcomes for a chat (newest first).
2127
+ *
2128
+ * Operator surface: the endpoint requires `chats:read` in addition to the
2129
+ * chat's own object authorization, so a chat owner reading their own chat
2130
+ * does not reach it. The response carries IDs and closed-vocabulary codes
2131
+ * only — no note body, summary, member fields, or provider messages.
2132
+ */
2133
+ async getChatEhrWritebackOutcomes(wid, chatId, options = {}) {
2134
+ const params = new URLSearchParams();
2135
+ if (options.limit !== void 0) params.append("limit", options.limit.toString());
2136
+ if (options.cursor) params.append("cursor", options.cursor);
2137
+ const queryString = params.toString();
2138
+ return this.fetch(
2139
+ `w/${wid}/chats/${chatId}/ehr-writeback-outcomes${queryString ? `?${queryString}` : ""}`
2140
+ );
2141
+ }
2077
2142
  /** Cancel a pending scheduled callback on a chat. */
2078
2143
  async cancelChatCallback(wid, chatId, callbackId) {
2079
2144
  return this.fetch(
@@ -2085,6 +2150,18 @@ var ChatsApi = class extends BaseApiClient {
2085
2150
  async getChatTodos(wid, chatId) {
2086
2151
  return this.fetch(`w/${wid}/chats/${chatId}/todos`);
2087
2152
  }
2153
+ /**
2154
+ * The caller's own live inline-connect link for a chat.
2155
+ *
2156
+ * An `inline_connect` prompt (`UiPromptPresented.connect`) names the
2157
+ * connection but carries no URL; fetch it here when the member chooses to
2158
+ * connect. 404 when nothing is live for the caller in this chat.
2159
+ */
2160
+ async getInlineConnectLink(wid, chatId, appSlug) {
2161
+ return this.fetch(
2162
+ `w/${wid}/chats/${chatId}/inline-connect/${encodeURIComponent(appSlug)}/link`
2163
+ );
2164
+ }
2088
2165
  /** Get loaded and revealed skills for a chat. */
2089
2166
  async getChatSkills(wid, chatId) {
2090
2167
  return this.fetch(`w/${wid}/chats/${chatId}/skills`);
@@ -2119,6 +2196,23 @@ var ChatsApi = class extends BaseApiClient {
2119
2196
  method: "PUT"
2120
2197
  });
2121
2198
  }
2199
+ /** Start an interaction within an existing Chat without changing its channel. */
2200
+ async createChatInteractionSession(wid, chatId, request) {
2201
+ return this.fetch(
2202
+ `w/${wid}/chats/${chatId}/interaction-sessions`,
2203
+ {
2204
+ method: "POST",
2205
+ body: JSON.stringify(request)
2206
+ }
2207
+ );
2208
+ }
2209
+ /** End one mode session and append its replacement in the same Chat. */
2210
+ async transitionChatInteractionSession(wid, chatId, sessionId, request) {
2211
+ return this.fetch(
2212
+ `w/${wid}/chats/${chatId}/interaction-sessions/${encodeURIComponent(sessionId)}/transition`,
2213
+ { method: "POST", body: JSON.stringify(request) }
2214
+ );
2215
+ }
2122
2216
  /** Create a new chat. */
2123
2217
  async createChat(wid, chat) {
2124
2218
  const { agentMemberId, ...rest } = chat;
@@ -2209,10 +2303,11 @@ var ChatsApi = class extends BaseApiClient {
2209
2303
  }
2210
2304
  /** List messages in a chat with optional pagination.
2211
2305
  * ``id`` is the numeric chat id (documented) or the chat uuid (accepted). */
2212
- async getChatMessages(wid, id, limit, offset) {
2306
+ async getChatMessages(wid, id, limit, offset, before) {
2213
2307
  const params = new URLSearchParams();
2214
2308
  if (limit) params.append("limit", limit.toString());
2215
2309
  if (offset) params.append("offset", offset.toString());
2310
+ if (before) params.append("before", before);
2216
2311
  return this.fetch(
2217
2312
  `w/${wid}/chats/${id}/messages${params.toString() ? `?${params.toString()}` : ""}`
2218
2313
  );
@@ -2632,6 +2727,35 @@ var DashboardsApi = class extends BaseApiClient {
2632
2727
 
2633
2728
  // src/api/data-types.ts
2634
2729
  var DataTypesApi = class extends BaseApiClient {
2730
+ /** Read the local Form's draft and optimistic publication counters. */
2731
+ async getDataTypeDraft(wid, id) {
2732
+ return this.fetch(`w/${wid}/data-types/${id}/schema-draft`);
2733
+ }
2734
+ /** Save a draft without changing the schema used to validate live records. */
2735
+ async saveDataTypeDraft(wid, id, request) {
2736
+ return this.fetch(`w/${wid}/data-types/${id}/schema-draft`, {
2737
+ method: "PUT",
2738
+ body: JSON.stringify(request)
2739
+ });
2740
+ }
2741
+ /** Publish the expected draft as the next immutable local schema version. */
2742
+ async publishDataTypeDraft(wid, id, request) {
2743
+ return this.fetch(`w/${wid}/data-types/${id}/schema-publish`, {
2744
+ method: "POST",
2745
+ body: JSON.stringify(request)
2746
+ });
2747
+ }
2748
+ /** List schema history newest first; use the last version as the next cursor. */
2749
+ async getDataTypeVersions(wid, id, options) {
2750
+ const params = new URLSearchParams();
2751
+ if (options?.beforeVersion !== void 0)
2752
+ params.set("beforeVersion", String(options.beforeVersion));
2753
+ if (options?.limit !== void 0) params.set("limit", String(options.limit));
2754
+ const query = params.toString();
2755
+ return this.fetch(
2756
+ `w/${wid}/data-types/${id}/schema-versions${query ? `?${query}` : ""}`
2757
+ );
2758
+ }
2635
2759
  /** List all data types for a workspace, optionally filtering by archived status. */
2636
2760
  async getDataTypes(wid, options) {
2637
2761
  const params = new URLSearchParams();
@@ -2700,7 +2824,6 @@ var DataTypesApi = class extends BaseApiClient {
2700
2824
  const params = new URLSearchParams();
2701
2825
  if (options?.memberId !== void 0) params.append("member_id", options.memberId.toString());
2702
2826
  if (options?.memberIds?.length) params.append("member_ids", options.memberIds.join(","));
2703
- if (options?.recordId !== void 0) params.append("record_id", options.recordId.toString());
2704
2827
  if (options?.search) params.append("search", options.search);
2705
2828
  if (options?.searchField) params.append("search_field", options.searchField);
2706
2829
  if (options?.dataRecordFilterId != null) {
@@ -2856,36 +2979,35 @@ function isUuid(value) {
2856
2979
 
2857
2980
  // src/api/devices.ts
2858
2981
  var DevicesApi = class extends BaseApiClient {
2859
- /** List devices visible to the caller (own devices, or all with devices:admin). */
2860
- async getDevices(wid, options = {}) {
2861
- const qs = options.mine ? "?mine=true" : "";
2862
- return this.fetch(`w/${wid}/devices${qs}`);
2982
+ /** List devices owned by the current Account. */
2983
+ async getDevices() {
2984
+ return this.fetch("account/devices");
2863
2985
  }
2864
- /** Fetch one device by UUID. Non-owners without devices:admin receive 404. */
2865
- async getDevice(wid, deviceUuid) {
2866
- return this.fetch(`w/${wid}/devices/${deviceUuid}`);
2986
+ /** Fetch one device owned by the current Account. Other devices return 404. */
2987
+ async getDevice(deviceUuid) {
2988
+ return this.fetch(`account/devices/${deviceUuid}`);
2867
2989
  }
2868
2990
  /** List shippable companion-device products (Lantern, later SKUs). */
2869
- async getDeviceKinds(wid) {
2870
- return this.fetch(`w/${wid}/devices/kinds`);
2991
+ async getDeviceKinds() {
2992
+ return this.fetch("account/devices/kinds");
2871
2993
  }
2872
- /** Claim a pairing code shown on a companion device. Requires devices:write. */
2873
- async claimDevicePairing(wid, body) {
2874
- return this.fetch(`w/${wid}/devices/pairing/claim`, {
2994
+ /** Claim a pairing code shown on a companion device for the current Account. */
2995
+ async claimDevicePairing(body) {
2996
+ return this.fetch("account/devices/pairing/claim", {
2875
2997
  method: "POST",
2876
2998
  body: JSON.stringify(body)
2877
2999
  });
2878
3000
  }
2879
- /** Update display name and/or LAN capability flags. Requires devices:write. */
2880
- async updateDevice(wid, deviceUuid, body) {
2881
- return this.fetch(`w/${wid}/devices/${deviceUuid}`, {
3001
+ /** Update display name and/or LAN capability flags on an owned device. */
3002
+ async updateDevice(deviceUuid, body) {
3003
+ return this.fetch(`account/devices/${deviceUuid}`, {
2882
3004
  method: "PATCH",
2883
3005
  body: JSON.stringify(body)
2884
3006
  });
2885
3007
  }
2886
- /** Revoke a device credential. The device must pair again. Requires devices:write. */
2887
- async revokeDevice(wid, deviceUuid) {
2888
- return this.fetch(`w/${wid}/devices/${deviceUuid}/revoke`, {
3008
+ /** Revoke an owned device credential. The device must pair again. */
3009
+ async revokeDevice(deviceUuid) {
3010
+ return this.fetch(`account/devices/${deviceUuid}/revoke`, {
2889
3011
  method: "POST",
2890
3012
  body: JSON.stringify({})
2891
3013
  });
@@ -3314,6 +3436,22 @@ var EventsApi = class extends BaseApiClient {
3314
3436
  }
3315
3437
  );
3316
3438
  }
3439
+ /**
3440
+ * Preview what would stop a draft Routine placing its scheduled outbound
3441
+ * calls — the Member voice opt-out, a missing member phone, or a
3442
+ * workspace number that is stale, archived, or not voice-enabled.
3443
+ * Non-persisting and advisory. The audience is reported as counts only,
3444
+ * never as Member rows.
3445
+ */
3446
+ async previewRoutineVoiceReadiness(wid, request) {
3447
+ return this.fetch(
3448
+ `w/${wid}/routines/preview-voice-readiness`,
3449
+ {
3450
+ method: "POST",
3451
+ body: JSON.stringify(request)
3452
+ }
3453
+ );
3454
+ }
3317
3455
  /** List routines with optional pagination and active status filtering. */
3318
3456
  async getRoutines(wid, options = {}) {
3319
3457
  const params = new URLSearchParams();
@@ -3323,6 +3461,8 @@ var EventsApi = class extends BaseApiClient {
3323
3461
  if (options.sortOrder) params.append("sortOrder", options.sortOrder);
3324
3462
  if (options.owner) params.append("owner", options.owner);
3325
3463
  if (options.ownerId) params.append("ownerId", options.ownerId.toString());
3464
+ if (options.agentId) params.append("agentId", options.agentId.toString());
3465
+ if (options.agentOnly) params.append("agentOnly", "true");
3326
3466
  return this.fetch(
3327
3467
  `w/${wid}/routines${params.toString() ? `?${params.toString()}` : ""}`
3328
3468
  );
@@ -4299,7 +4439,14 @@ var InboxesApi = class extends BaseApiClient {
4299
4439
  async getInboxes(wid) {
4300
4440
  return this.fetch(`w/${wid}/inboxes`);
4301
4441
  }
4302
- /** Get an inbox by ID. */
4442
+ /**
4443
+ * Get an inbox by ID or UUID.
4444
+ *
4445
+ * The route has always taken either (`inbox_id: str = Path(..., description=
4446
+ * "Inbox ID or UUID")`); the signature said `number`, which put the UUID path
4447
+ * out of reach for a caller holding an inbox ref from the activity feed —
4448
+ * where refs are UUID-only by design.
4449
+ */
4303
4450
  async getInbox(wid, id) {
4304
4451
  return this.fetch(`w/${wid}/inboxes/${id}`);
4305
4452
  }
@@ -5017,17 +5164,11 @@ var MembersApi = class extends BaseApiClient {
5017
5164
  * operator can decide whether to skip or explicitly overwrite before
5018
5165
  * committing. Requires MEMBERS_ADMIN and is bulk-PHI audited server-side.
5019
5166
  */
5020
- async previewImportMembers(wid, file, newMemberRoleId, options) {
5167
+ async previewImportMembers(wid, file, newMemberRoleId) {
5021
5168
  const formData = new FormData();
5022
5169
  formData.append("file", file);
5023
5170
  const params = new URLSearchParams();
5024
5171
  params.append("new_member_role_id", newMemberRoleId.toString());
5025
- if (options?.trustEmailAddresses) {
5026
- params.append("trust_email_addresses", "true");
5027
- }
5028
- if (options?.trustPhoneNumbers) {
5029
- params.append("trust_phone_numbers", "true");
5030
- }
5031
5172
  const response = await this.fetchRaw(
5032
5173
  `w/${wid}/members/import/preview?${params.toString()}`,
5033
5174
  {
@@ -5054,12 +5195,6 @@ var MembersApi = class extends BaseApiClient {
5054
5195
  formData.append("file", file);
5055
5196
  const params = new URLSearchParams();
5056
5197
  params.append("new_member_role_id", newMemberRoleId.toString());
5057
- if (options?.trustEmailAddresses) {
5058
- params.append("trust_email_addresses", "true");
5059
- }
5060
- if (options?.trustPhoneNumbers) {
5061
- params.append("trust_phone_numbers", "true");
5062
- }
5063
5198
  if (options?.identityConflictPolicy) {
5064
5199
  params.append("identity_conflict_policy", options.identityConflictPolicy);
5065
5200
  }
@@ -5308,13 +5443,179 @@ var MembersApi = class extends BaseApiClient {
5308
5443
  async getMemberSyncLinks(wid, memberId) {
5309
5444
  return this.fetch(`w/${wid}/members/${memberId}/sync-links`);
5310
5445
  }
5446
+ async getMemberRelationships(wid, memberId, params) {
5447
+ const search = new URLSearchParams();
5448
+ if (params?.page) search.set("page", String(params.page));
5449
+ if (params?.pageSize) search.set("pageSize", String(params.pageSize));
5450
+ if (params?.kind) search.set("kind", params.kind);
5451
+ const qs = search.toString();
5452
+ return this.fetch(
5453
+ `w/${wid}/members/${memberId}/relationships${qs ? `?${qs}` : ""}`
5454
+ );
5455
+ }
5456
+ async createMemberRelationship(wid, memberId, body) {
5457
+ return this.fetch(`w/${wid}/members/${memberId}/relationships`, {
5458
+ method: "POST",
5459
+ body: JSON.stringify(body)
5460
+ });
5461
+ }
5462
+ async archiveMemberRelationship(wid, memberId, relationshipId) {
5463
+ return this.fetch(
5464
+ `w/${wid}/members/${memberId}/relationships/${relationshipId}`,
5465
+ { method: "DELETE" }
5466
+ );
5467
+ }
5311
5468
  };
5312
5469
 
5313
- // src/api/activity-timeline.ts
5314
- var ActivityTimelineApi = class extends BaseApiClient {
5315
- /** One page of activity. Omit `cursor` for a fresh snapshot. */
5316
- async queryActivityTimeline(wid, request = {}) {
5317
- return this.fetch(`w/${wid}/activity-timeline/query`, {
5470
+ // src/api/activity.ts
5471
+ var ActivityApi = class extends BaseApiClient {
5472
+ /** The account mount: this caller's whole estate, at any grain. */
5473
+ async queryActivity(request) {
5474
+ return this.fetch("activity/query", {
5475
+ method: "POST",
5476
+ body: JSON.stringify(request)
5477
+ });
5478
+ }
5479
+ /**
5480
+ * Latest admitted event for each workspace-qualified Activity subject.
5481
+ * Scope authorization and any event-type leaf authorization are both
5482
+ * applied before a subject is returned.
5483
+ */
5484
+ async queryActivityLatestSubjects(request) {
5485
+ return this.fetch("activity/latest-subjects", {
5486
+ method: "POST",
5487
+ body: JSON.stringify(request)
5488
+ });
5489
+ }
5490
+ /**
5491
+ * The account mount's priority lane — one queue per human. `openedAfter`
5492
+ * may bound the active backlog without changing the priority policy.
5493
+ */
5494
+ async queryActivityOpenItems(request = {}) {
5495
+ return this.fetch("activity/open-items", {
5496
+ method: "POST",
5497
+ body: JSON.stringify(request)
5498
+ });
5499
+ }
5500
+ /**
5501
+ * The account mount's one view: one stream of occurrences, some carrying
5502
+ * open state. The window bounds the event axis; open items older than it
5503
+ * arrive as `olderOpenCount`, never hidden.
5504
+ */
5505
+ async queryActivityOneView(request) {
5506
+ return this.fetch("activity/one-view", {
5507
+ method: "POST",
5508
+ body: JSON.stringify(request)
5509
+ });
5510
+ }
5511
+ /** The account mount's badge numbers. */
5512
+ async getActivityCounts(request = {}) {
5513
+ return this.fetch("activity/counts", {
5514
+ method: "POST",
5515
+ body: JSON.stringify(request)
5516
+ });
5517
+ }
5518
+ /**
5519
+ * What this caller's estate admits, so a client renders honest controls.
5520
+ *
5521
+ * Account mount only, and deliberately so: the org and workspace mounts
5522
+ * answer the same question through the surfaces that already serve their
5523
+ * membership. Not an authorization decision — every read re-derives that.
5524
+ */
5525
+ async getActivityCapabilities() {
5526
+ return this.fetch("activity/capabilities", { method: "GET" });
5527
+ }
5528
+ /** The org mount. `org:info` is the entry gate; `org:read` widens the rows. */
5529
+ async queryOrgActivity(orgUuid, request) {
5530
+ return this.fetch(`o/${orgUuid}/activity/query`, {
5531
+ method: "POST",
5532
+ body: JSON.stringify(request)
5533
+ });
5534
+ }
5535
+ async queryOrgActivityLatestSubjects(orgUuid, request) {
5536
+ return this.fetch(`o/${orgUuid}/activity/latest-subjects`, {
5537
+ method: "POST",
5538
+ body: JSON.stringify(request)
5539
+ });
5540
+ }
5541
+ /** The org mount's priority lane. */
5542
+ async queryOrgActivityOpenItems(orgUuid, request = {}) {
5543
+ return this.fetch(`o/${orgUuid}/activity/open-items`, {
5544
+ method: "POST",
5545
+ body: JSON.stringify(request)
5546
+ });
5547
+ }
5548
+ /** The org mount's one view. */
5549
+ async queryOrgActivityOneView(orgUuid, request) {
5550
+ return this.fetch(`o/${orgUuid}/activity/one-view`, {
5551
+ method: "POST",
5552
+ body: JSON.stringify(request)
5553
+ });
5554
+ }
5555
+ /** The org mount's badge numbers. */
5556
+ async getOrgActivityCounts(orgUuid, request = {}) {
5557
+ return this.fetch(`o/${orgUuid}/activity/counts`, {
5558
+ method: "POST",
5559
+ body: JSON.stringify(request)
5560
+ });
5561
+ }
5562
+ /** The workspace mount. The request's own member session carries its scopes. */
5563
+ async queryWorkspaceActivity(workspaceUuid, request) {
5564
+ return this.fetch(`w/${workspaceUuid}/activity/query`, {
5565
+ method: "POST",
5566
+ body: JSON.stringify(request)
5567
+ });
5568
+ }
5569
+ async queryWorkspaceActivityLatestSubjects(workspaceUuid, request) {
5570
+ return this.fetch(`w/${workspaceUuid}/activity/latest-subjects`, {
5571
+ method: "POST",
5572
+ body: JSON.stringify(request)
5573
+ });
5574
+ }
5575
+ /** The workspace mount's priority lane. */
5576
+ async queryWorkspaceActivityOpenItems(workspaceUuid, request = {}) {
5577
+ return this.fetch(`w/${workspaceUuid}/activity/open-items`, {
5578
+ method: "POST",
5579
+ body: JSON.stringify(request)
5580
+ });
5581
+ }
5582
+ /** The workspace mount's one view. */
5583
+ async queryWorkspaceActivityOneView(workspaceUuid, request) {
5584
+ return this.fetch(`w/${workspaceUuid}/activity/one-view`, {
5585
+ method: "POST",
5586
+ body: JSON.stringify(request)
5587
+ });
5588
+ }
5589
+ /** The workspace mount's badge numbers. */
5590
+ async getWorkspaceActivityCounts(workspaceUuid, request = {}) {
5591
+ return this.fetch(`w/${workspaceUuid}/activity/counts`, {
5592
+ method: "POST",
5593
+ body: JSON.stringify(request)
5594
+ });
5595
+ }
5596
+ /**
5597
+ * Hydrate a page of typed refs in one round trip.
5598
+ *
5599
+ * The relief valve the design names for chatty hydration, and the by-UUID
5600
+ * read path most entity kinds otherwise lack: nineteen kinds resolve here,
5601
+ * each through the workspace's own live authorizers under the caller's
5602
+ * session. One request per workspace per listing, instead of one per ref.
5603
+ *
5604
+ * **Every requested ref comes back**, in the order it was sent and
5605
+ * deduplicated on `(kind, uuid)`. A ref the caller may not see is an entry
5606
+ * with `status: 'unresolved'` — never a 404, and never an omission, so a
5607
+ * page's ability to render never depends on what it happens to name.
5608
+ * `status: 'unsupported'` means this build has no by-UUID path for that
5609
+ * kind at all (account, org, workspace, domain, subscription and the
5610
+ * commerce kinds; see the resolve registry for each one's reason) — those
5611
+ * resolve through the mount that owns them, and retrying here will not
5612
+ * help.
5613
+ *
5614
+ * PHI: resolved labels are member-identifying data. They belong in the UI
5615
+ * and nowhere else — never a log line, never an error message.
5616
+ */
5617
+ async resolveEntityRefs(workspaceUuid, request) {
5618
+ return this.fetch(`w/${workspaceUuid}/entity-refs/resolve`, {
5318
5619
  method: "POST",
5319
5620
  body: JSON.stringify(request)
5320
5621
  });
@@ -5508,6 +5809,10 @@ var MondayIntegrationApi = class extends BaseApiClient {
5508
5809
 
5509
5810
  // src/api/intervention-requests.ts
5510
5811
  var InterventionRequestsApi = class extends BaseApiClient {
5812
+ /** List every visible Chat that currently needs attention in Agent Mode. */
5813
+ async getAgentModeAttention(wid) {
5814
+ return this.fetch(`w/${wid}/agent-mode/attention`);
5815
+ }
5511
5816
  /** List intervention requests in a workspace, newest first. */
5512
5817
  async getInterventionRequests(wid, params = {}) {
5513
5818
  const query = new URLSearchParams();
@@ -5521,6 +5826,23 @@ var InterventionRequestsApi = class extends BaseApiClient {
5521
5826
  `w/${wid}/intervention-requests${qs ? `?${qs}` : ""}`
5522
5827
  );
5523
5828
  }
5829
+ /**
5830
+ * Resolve one intervention request. One row, one resolution — whoever takes
5831
+ * it closes it for everyone who was notified. Resolving an already-resolved
5832
+ * request is a 409 conflict; a non-escalation request is a 409 too.
5833
+ *
5834
+ * The JSON body (empty when no note is supplied) is required as a CSRF
5835
+ * barrier (GRA-6284), so a cross-site form POST cannot reach it.
5836
+ */
5837
+ async resolveInterventionRequest(wid, requestId, params = {}) {
5838
+ return this.fetch(
5839
+ `w/${wid}/intervention-requests/${requestId}/resolve`,
5840
+ {
5841
+ method: "POST",
5842
+ body: JSON.stringify(params)
5843
+ }
5844
+ );
5845
+ }
5524
5846
  };
5525
5847
 
5526
5848
  // src/api/notification-rules.ts
@@ -5602,12 +5924,6 @@ var OperatorApi = class extends BaseApiClient {
5602
5924
  async getPresenceStatus(wid) {
5603
5925
  return this.fetch(`w/${wid}/presence/me`);
5604
5926
  }
5605
- /** Disconnect the current member's presence session. */
5606
- async disconnectPresence(wid) {
5607
- return this.fetch(`w/${wid}/presence/disconnect-self`, {
5608
- method: "POST"
5609
- });
5610
- }
5611
5927
  // Operator chat message methods
5612
5928
  /** Get paginated chat messages for an operator chat. */
5613
5929
  async getOperatorChatMessages(wid, chatId, limit = 50, offset = 0) {
@@ -6177,6 +6493,28 @@ var OrgApi = class extends BaseApiClient {
6177
6493
  async getLegalEntity(orgUuid, legalEntityUuid) {
6178
6494
  return this.fetch(`o/${orgUuid}/legal-entities/${legalEntityUuid}`);
6179
6495
  }
6496
+ /**
6497
+ * Read one registration draft for a legal entity.
6498
+ *
6499
+ * A draft is what the operator has typed but not submitted. It exists so
6500
+ * data entry is never gated on a prerequisite: someone can write down the
6501
+ * caller-ID name today and submit it the day the business is verified.
6502
+ */
6503
+ async getRegistrationDraft(orgUuid, legalEntityUuid, kind) {
6504
+ return this.fetch(
6505
+ `o/${orgUuid}/legal-entities/${legalEntityUuid}/registration-drafts/${kind}`
6506
+ );
6507
+ }
6508
+ /**
6509
+ * Save one registration draft. Always accepted — the server refuses only
6510
+ * an oversized body, never an unfinished one.
6511
+ */
6512
+ async saveRegistrationDraft(orgUuid, legalEntityUuid, kind, data) {
6513
+ return this.fetch(
6514
+ `o/${orgUuid}/legal-entities/${legalEntityUuid}/registration-drafts/${kind}`,
6515
+ { method: "PUT", body: JSON.stringify({ data }) }
6516
+ );
6517
+ }
6180
6518
  /** Cached voice trust product state (CNAM / SHAKEN-STIR / Voice Integrity) for one legal entity. */
6181
6519
  async getVoiceTrustProducts(orgUuid, legalEntityUuid) {
6182
6520
  return this.fetch(
@@ -6350,6 +6688,42 @@ var OrgApi = class extends BaseApiClient {
6350
6688
  }
6351
6689
  );
6352
6690
  }
6691
+ // =========================================================================
6692
+ // Organization webhook endpoints (GRA-8314)
6693
+ // =========================================================================
6694
+ async listOrgWebhookEndpoints(orgIdOrUuid) {
6695
+ return this.fetch(`o/${orgIdOrUuid}/webhooks`);
6696
+ }
6697
+ /**
6698
+ * The subscribable event-type vocabulary for the org UI's event-type
6699
+ * picker — exactly what the create/update validators accept, so the UI
6700
+ * never offers a type the API would reject.
6701
+ */
6702
+ async listOrgWebhookEventTypes(orgIdOrUuid) {
6703
+ return this.fetch(`o/${orgIdOrUuid}/webhooks/event-types`);
6704
+ }
6705
+ async createOrgWebhookEndpoint(orgIdOrUuid, data) {
6706
+ return this.fetch(`o/${orgIdOrUuid}/webhooks`, {
6707
+ method: "POST",
6708
+ body: JSON.stringify(data)
6709
+ });
6710
+ }
6711
+ async updateOrgWebhookEndpoint(orgIdOrUuid, endpointUuid, data) {
6712
+ return this.fetch(`o/${orgIdOrUuid}/webhooks/${endpointUuid}`, {
6713
+ method: "PATCH",
6714
+ body: JSON.stringify(data)
6715
+ });
6716
+ }
6717
+ async deleteOrgWebhookEndpoint(orgIdOrUuid, endpointUuid) {
6718
+ return this.fetch(`o/${orgIdOrUuid}/webhooks/${endpointUuid}`, {
6719
+ method: "DELETE"
6720
+ });
6721
+ }
6722
+ async listOrgWebhookEndpointDeliveries(orgIdOrUuid, endpointUuid, limit = 50) {
6723
+ return this.fetch(
6724
+ `o/${orgIdOrUuid}/webhooks/${endpointUuid}/deliveries?limit=${limit}`
6725
+ );
6726
+ }
6353
6727
  };
6354
6728
  function businessProfilePath(orgUuid, legalEntityUuid) {
6355
6729
  return legalEntityUuid ? `o/${orgUuid}/legal-entities/${legalEntityUuid}/business-profile` : `o/${orgUuid}/business-profile`;
@@ -6770,6 +7144,8 @@ var PersonasApi = class extends BaseApiClient {
6770
7144
  const q = new URLSearchParams();
6771
7145
  if (params?.page !== void 0) q.set("page", String(params.page));
6772
7146
  if (params?.pageSize !== void 0) q.set("pageSize", String(params.pageSize));
7147
+ if (params?.includeArchived !== void 0)
7148
+ q.set("includeArchived", String(params.includeArchived));
6773
7149
  const qs = q.toString() ? `?${q.toString()}` : "";
6774
7150
  return this.fetch(`w/${wid}/personas${qs}`);
6775
7151
  }
@@ -6788,6 +7164,18 @@ var PersonasApi = class extends BaseApiClient {
6788
7164
  body: JSON.stringify(data)
6789
7165
  });
6790
7166
  }
7167
+ async archivePersona(wid, id) {
7168
+ return this.fetch(`w/${wid}/personas/${id}/archive`, {
7169
+ method: "POST",
7170
+ body: JSON.stringify({})
7171
+ });
7172
+ }
7173
+ async unarchivePersona(wid, id) {
7174
+ return this.fetch(`w/${wid}/personas/${id}/unarchive`, {
7175
+ method: "POST",
7176
+ body: JSON.stringify({})
7177
+ });
7178
+ }
6791
7179
  async deletePersona(wid, id) {
6792
7180
  return this.fetch(`w/${wid}/personas/${id}`, { method: "DELETE" });
6793
7181
  }
@@ -8462,6 +8850,59 @@ var JourneysApi = class extends BaseApiClient {
8462
8850
  async getJourneyAuthoring(wid, journeyId) {
8463
8851
  return this.fetch(`w/${wid}/journeys/${journeyId}/authoring`);
8464
8852
  }
8853
+ /**
8854
+ * Atomically replace a v2 Journey's whole definition (Journey v2 plan §3.8).
8855
+ *
8856
+ * ONE request carries the ordered touches, the wait into each touch, the
8857
+ * ordered Endings, action associations, goals, and
8858
+ * `expectedUpdatedAt` for optimistic concurrency. It is a full replacement,
8859
+ * not a patch — omitting `goals` is the one exception and leaves them alone.
8860
+ *
8861
+ * Returns the AUTHORING projection (`Journey`): the caller just wrote the
8862
+ * CEL and holds the `journeys:write` scope that authorizes reading it back.
8863
+ *
8864
+ * Refusals are HTTP 409 with a stable `code`:
8865
+ * * `journey_v2_execution_model_mismatch` — the Journey is legacy; use the
8866
+ * step/connection/goal endpoints.
8867
+ * * `journey_v2_structural_edit_not_allowed` — it is live; pause it first.
8868
+ * * `journey_v2_definition_conflict` — someone saved first; reload.
8869
+ * * `journey_v2_invalid_topology` — the resulting graph is not executable;
8870
+ * the body carries `issues` (codes and resource uuids, never CEL).
8871
+ */
8872
+ async putJourneyV2Definition(wid, journeyId, data) {
8873
+ return this.fetch(`w/${wid}/journeys/${journeyId}/v2-definition`, {
8874
+ method: "PUT",
8875
+ body: JSON.stringify(data)
8876
+ });
8877
+ }
8878
+ /**
8879
+ * Dry-run the v2 publish validator against the STORED definition.
8880
+ *
8881
+ * Answers "could I activate this right now?" without attempting the
8882
+ * transition. Issues carry closed codes and resource uuids only — never CEL
8883
+ * and never member data — so they are safe to render or log.
8884
+ */
8885
+ async getJourneyV2Validation(wid, journeyId) {
8886
+ return this.fetch(
8887
+ `w/${wid}/journeys/${journeyId}/v2-definition/validation`
8888
+ );
8889
+ }
8890
+ /**
8891
+ * MemberFilter ids and names, for the Journey authoring picker.
8892
+ *
8893
+ * A v2 wait, route or Ending may carry a structured MemberFilter predicate
8894
+ * and the author selects it by NAME (rule-filters plan §3.10). This is the
8895
+ * catalogue for that control and the whole of what it needs: two scalars per
8896
+ * filter, no `query` predicate, no rules, no counts.
8897
+ *
8898
+ * Authorized on `journeys:write` alone — deliberately NOT the Members
8899
+ * surface's `MembersApi.getMemberFilters`, which is `members:read`
8900
+ * because it returns each filter's predicate. Journey authoring should not
8901
+ * require Member-read access to name a cohort.
8902
+ */
8903
+ async getJourneyFilterOptions(wid) {
8904
+ return this.fetch(`w/${wid}/journeys/filter-options`);
8905
+ }
8465
8906
  /** Create a new journey. Returns the READ projection (`JourneyRead`). */
8466
8907
  async createJourney(wid, data) {
8467
8908
  return this.fetch(`w/${wid}/journeys`, {
@@ -8469,7 +8910,14 @@ var JourneysApi = class extends BaseApiClient {
8469
8910
  body: JSON.stringify(data)
8470
8911
  });
8471
8912
  }
8472
- /** Update an existing journey. Returns the READ projection (`JourneyRead`). */
8913
+ /**
8914
+ * Update an existing journey. Returns the READ projection (`JourneyRead`).
8915
+ *
8916
+ * `executionModel` is excluded: it is a CREATE-only field. Flipping a live
8917
+ * Journey's engine is a guarded, audited migration operation (Journey v2
8918
+ * plan §3.11), so the server has no update counterpart and sending one here
8919
+ * would silently do nothing.
8920
+ */
8473
8921
  async updateJourney(wid, journeyId, data) {
8474
8922
  return this.fetch(`w/${wid}/journeys/${journeyId}`, {
8475
8923
  method: "PUT",
@@ -8576,8 +9024,6 @@ var JourneysApi = class extends BaseApiClient {
8576
9024
  qs.set("currentTaskId", String(params.currentTaskId));
8577
9025
  if (params?.runtimeFailureEdgeId !== void 0)
8578
9026
  qs.set("runtimeFailureEdgeId", String(params.runtimeFailureEdgeId));
8579
- if (params?.memberJourneyId !== void 0)
8580
- qs.set("memberJourneyId", String(params.memberJourneyId));
8581
9027
  const query = qs.toString();
8582
9028
  return this.fetch(
8583
9029
  `w/${wid}/journeys/${journeyId}/members${query ? `?${query}` : ""}`
@@ -8731,6 +9177,15 @@ var WorkflowsApi = class extends BaseApiClient {
8731
9177
  async getWorkflow(wid, id) {
8732
9178
  return this.fetch(`w/${wid}/workflows/${id}`);
8733
9179
  }
9180
+ async getWorkflowOpeningTurnConversionReport(wid, id) {
9181
+ return this.fetch(`w/${wid}/workflows/${id}/opening-turn/conversion-report`);
9182
+ }
9183
+ async convertWorkflowStartTaskOpeningMessage(wid, id, expectedRuleId) {
9184
+ return this.fetch(`w/${wid}/workflows/${id}/opening-turn/convert-start-task-message`, {
9185
+ method: "POST",
9186
+ body: JSON.stringify({ expectedRuleId })
9187
+ });
9188
+ }
8734
9189
  /** Get activity metrics for a single workflow. */
8735
9190
  async getWorkflowActivity(wid, id, options) {
8736
9191
  const params = options?.days ? `?days=${options.days}` : "";
@@ -9222,7 +9677,9 @@ var Scope = /* @__PURE__ */ ((Scope2) => {
9222
9677
  var BulkMemberResultStatus = {
9223
9678
  created: "created",
9224
9679
  updated: "updated",
9225
- failed: "failed"
9680
+ failed: "failed",
9681
+ conflict: "conflict",
9682
+ skipped: "skipped"
9226
9683
  };
9227
9684
  var MemberImportMatchInfoMatchType = {
9228
9685
  external_id: "external_id",
@@ -9236,6 +9693,7 @@ var MemberImportPreviewRowAction = {
9236
9693
  update: "update",
9237
9694
  unchanged: "unchanged",
9238
9695
  conflict: "conflict",
9696
+ skipped: "skipped",
9239
9697
  error: "error"
9240
9698
  };
9241
9699
 
@@ -9384,6 +9842,8 @@ var EventRuleActionType = /* @__PURE__ */ ((EventRuleActionType2) => {
9384
9842
  EventRuleActionType2["CONNECTOR_OPERATION"] = "connector:operation";
9385
9843
  EventRuleActionType2["ECW_REFRESH_MEMBER_ENCOUNTERS"] = "ecw:refresh_member_encounters";
9386
9844
  EventRuleActionType2["PLAY_AUDIO"] = "audio:play";
9845
+ EventRuleActionType2["CHARLESTON_SEND_PMD_PAGE"] = "charleston:send_pmd_page";
9846
+ EventRuleActionType2["PATIENTSYNC_TRANSFER"] = "patientsync:transfer";
9387
9847
  return EventRuleActionType2;
9388
9848
  })(EventRuleActionType || {});
9389
9849
  function eventRuleActionParams(params) {
@@ -9405,6 +9865,7 @@ var WorkspaceFeature = /* @__PURE__ */ ((WorkspaceFeature2) => {
9405
9865
  WorkspaceFeature2["BROWSER"] = "browser";
9406
9866
  WorkspaceFeature2["WEB_SEARCH"] = "web_search";
9407
9867
  WorkspaceFeature2["CALENDAR"] = "calendar";
9868
+ WorkspaceFeature2["JOURNEY_V2_EDITOR"] = "journey_v2_editor";
9408
9869
  WorkspaceFeature2["EXPERIMENTS"] = "experiments";
9409
9870
  WorkspaceFeature2["MAILBOX_USER_INPUT"] = "mailbox_user_input";
9410
9871
  WorkspaceFeature2["FORKED_TRAJECTORIES"] = "forked_trajectories";
@@ -9567,6 +10028,7 @@ var ModelProvider = {
9567
10028
  elevenlabs: "elevenlabs",
9568
10029
  deepgram: "deepgram",
9569
10030
  xai: "xai",
10031
+ fireworks: "fireworks",
9570
10032
  custom: "custom"
9571
10033
  };
9572
10034
  var ModelType = {
@@ -9669,6 +10131,24 @@ var FhirClientType = /* @__PURE__ */ ((FhirClientType2) => {
9669
10131
  return FhirClientType2;
9670
10132
  })(FhirClientType || {});
9671
10133
 
10134
+ // src/types/generated/qualification.ts
10135
+ var TestChatRunLane = {
10136
+ text: "text",
10137
+ web_realtime: "web_realtime",
10138
+ core_agent_only: "core_agent_only",
10139
+ unsupported: "unsupported",
10140
+ unknown: "unknown"
10141
+ };
10142
+ var TestChatRunOutcome = {
10143
+ simulator_end: "simulator_end",
10144
+ terminal_tool: "terminal_tool",
10145
+ agent_silent: "agent_silent",
10146
+ max_turns: "max_turns",
10147
+ human_end: "human_end",
10148
+ configuration_failure: "configuration_failure",
10149
+ instrument_failure: "instrument_failure"
10150
+ };
10151
+
9672
10152
  // src/types/qualification-types.ts
9673
10153
  var CriterionType = /* @__PURE__ */ ((CriterionType2) => {
9674
10154
  CriterionType2["EXPRESSION"] = "expression";
@@ -9727,21 +10207,268 @@ var ConsentMethod = /* @__PURE__ */ ((ConsentMethod2) => {
9727
10207
  return ConsentMethod2;
9728
10208
  })(ConsentMethod || {});
9729
10209
 
9730
- // src/api/workspace-invitations.ts
9731
- var WorkspaceInvitationsApi = class extends BaseApiClient {
9732
- /**
9733
- * List user's own invitations (both org and workspace).
9734
- * For admin listing of a specific workspace's invitations, use listWorkspaceInvitationsAdmin.
9735
- */
9736
- async listWorkspaceInvitations(params) {
9737
- const queryParams = new URLSearchParams();
9738
- if (params?.status) queryParams.append("status", params.status);
9739
- if (params?.page) queryParams.append("page", params.page.toString());
9740
- if (params?.pageSize) queryParams.append("page_size", params.pageSize.toString());
9741
- const queryString = queryParams.toString();
9742
- const url = `invitations${queryString ? `?${queryString}` : ""}`;
9743
- return this.fetch(url);
9744
- }
10210
+ // src/types/generated/member_relationship.ts
10211
+ var MemberRelationshipKind = {
10212
+ parent_of: "parent_of",
10213
+ sibling_of: "sibling_of",
10214
+ spouse_of: "spouse_of",
10215
+ caregiver_of: "caregiver_of",
10216
+ emergency_contact_of: "emergency_contact_of",
10217
+ next_of_kin_of: "next_of_kin_of",
10218
+ legal_guardian_of: "legal_guardian_of",
10219
+ healthcare_agent_of: "healthcare_agent_of",
10220
+ doctor_of: "doctor_of",
10221
+ primary_contact_of: "primary_contact_of"
10222
+ };
10223
+ var RelatedMemberRole = {
10224
+ parent: "parent",
10225
+ child: "child",
10226
+ sibling: "sibling",
10227
+ spouse: "spouse",
10228
+ caregiver: "caregiver",
10229
+ care_recipient: "care_recipient",
10230
+ emergency_contact: "emergency_contact",
10231
+ emergency_contact_for: "emergency_contact_for",
10232
+ next_of_kin: "next_of_kin",
10233
+ next_of_kin_for: "next_of_kin_for",
10234
+ legal_guardian: "legal_guardian",
10235
+ legal_guardian_for: "legal_guardian_for",
10236
+ healthcare_agent: "healthcare_agent",
10237
+ healthcare_agent_for: "healthcare_agent_for",
10238
+ doctor: "doctor",
10239
+ patient: "patient",
10240
+ primary_contact: "primary_contact",
10241
+ primary_contact_for: "primary_contact_for"
10242
+ };
10243
+ var RelationshipCardinality = {
10244
+ many_to_many: "many_to_many",
10245
+ one_to_one: "one_to_one",
10246
+ one_per_target: "one_per_target"
10247
+ };
10248
+
10249
+ // src/types/generated/member_relationship_catalog.ts
10250
+ var MEMBER_RELATIONSHIP_KINDS = [
10251
+ {
10252
+ "kind": "parent_of",
10253
+ "cardinality": "many_to_many",
10254
+ "symmetric": false,
10255
+ "grantsChartAccess": false,
10256
+ "roles": [
10257
+ {
10258
+ "role": "parent",
10259
+ "label": "Parent",
10260
+ "inverseLabel": "Child",
10261
+ "description": "This person is a parent of the member. For a minor, also add Legal guardian if they should read the chart."
10262
+ },
10263
+ {
10264
+ "role": "child",
10265
+ "label": "Child",
10266
+ "inverseLabel": "Parent",
10267
+ "description": "This person is a child of the member."
10268
+ }
10269
+ ]
10270
+ },
10271
+ {
10272
+ "kind": "sibling_of",
10273
+ "cardinality": "many_to_many",
10274
+ "symmetric": true,
10275
+ "grantsChartAccess": false,
10276
+ "roles": [
10277
+ {
10278
+ "role": "sibling",
10279
+ "label": "Sibling",
10280
+ "inverseLabel": "Sibling",
10281
+ "description": "These members are siblings."
10282
+ }
10283
+ ]
10284
+ },
10285
+ {
10286
+ "kind": "spouse_of",
10287
+ "cardinality": "one_to_one",
10288
+ "symmetric": true,
10289
+ "grantsChartAccess": false,
10290
+ "roles": [
10291
+ {
10292
+ "role": "spouse",
10293
+ "label": "Spouse",
10294
+ "inverseLabel": "Spouse",
10295
+ "description": "These members are spouses or partners."
10296
+ }
10297
+ ]
10298
+ },
10299
+ {
10300
+ "kind": "caregiver_of",
10301
+ "cardinality": "many_to_many",
10302
+ "symmetric": false,
10303
+ "grantsChartAccess": false,
10304
+ "roles": [
10305
+ {
10306
+ "role": "caregiver",
10307
+ "label": "Caregiver",
10308
+ "inverseLabel": "Care recipient",
10309
+ "description": "This person provides care for the member at home."
10310
+ },
10311
+ {
10312
+ "role": "care_recipient",
10313
+ "label": "Care recipient",
10314
+ "inverseLabel": "Caregiver",
10315
+ "description": "This person receives care from the member."
10316
+ }
10317
+ ]
10318
+ },
10319
+ {
10320
+ "kind": "emergency_contact_of",
10321
+ "cardinality": "many_to_many",
10322
+ "symmetric": false,
10323
+ "grantsChartAccess": false,
10324
+ "roles": [
10325
+ {
10326
+ "role": "emergency_contact",
10327
+ "label": "Emergency contact",
10328
+ "inverseLabel": "Emergency contact for",
10329
+ "description": "This person is the member's emergency contact."
10330
+ },
10331
+ {
10332
+ "role": "emergency_contact_for",
10333
+ "label": "Emergency contact for",
10334
+ "inverseLabel": "Emergency contact",
10335
+ "description": "The member is listed as this person's emergency contact."
10336
+ }
10337
+ ]
10338
+ },
10339
+ {
10340
+ "kind": "next_of_kin_of",
10341
+ "cardinality": "one_per_target",
10342
+ "symmetric": false,
10343
+ "grantsChartAccess": false,
10344
+ "roles": [
10345
+ {
10346
+ "role": "next_of_kin",
10347
+ "label": "Next of kin",
10348
+ "inverseLabel": "Next of kin for",
10349
+ "description": "This person is the member's designated next of kin. A member has at most one."
10350
+ },
10351
+ {
10352
+ "role": "next_of_kin_for",
10353
+ "label": "Next of kin for",
10354
+ "inverseLabel": "Next of kin",
10355
+ "description": "The member is this person's designated next of kin."
10356
+ }
10357
+ ]
10358
+ },
10359
+ {
10360
+ "kind": "legal_guardian_of",
10361
+ "cardinality": "many_to_many",
10362
+ "symmetric": false,
10363
+ "grantsChartAccess": true,
10364
+ "roles": [
10365
+ {
10366
+ "role": "legal_guardian",
10367
+ "label": "Legal guardian",
10368
+ "inverseLabel": "Legal guardian for",
10369
+ "description": "Court-appointed guardian, or parent/person with parental responsibility for a minor."
10370
+ },
10371
+ {
10372
+ "role": "legal_guardian_for",
10373
+ "label": "Legal guardian for",
10374
+ "inverseLabel": "Legal guardian",
10375
+ "description": "The member is this person's legal guardian."
10376
+ }
10377
+ ]
10378
+ },
10379
+ {
10380
+ "kind": "healthcare_agent_of",
10381
+ "cardinality": "many_to_many",
10382
+ "symmetric": false,
10383
+ "grantsChartAccess": true,
10384
+ "roles": [
10385
+ {
10386
+ "role": "healthcare_agent",
10387
+ "label": "Healthcare agent",
10388
+ "inverseLabel": "Healthcare agent for",
10389
+ "description": "Healthcare power of attorney or health proxy."
10390
+ },
10391
+ {
10392
+ "role": "healthcare_agent_for",
10393
+ "label": "Healthcare agent for",
10394
+ "inverseLabel": "Healthcare agent",
10395
+ "description": "The member is this person's healthcare agent (healthcare power of attorney or health proxy)."
10396
+ }
10397
+ ]
10398
+ },
10399
+ {
10400
+ "kind": "doctor_of",
10401
+ "cardinality": "many_to_many",
10402
+ "symmetric": false,
10403
+ "grantsChartAccess": true,
10404
+ "roles": [
10405
+ {
10406
+ "role": "doctor",
10407
+ "label": "Doctor",
10408
+ "inverseLabel": "Patient",
10409
+ "description": "This person is a treating clinician for the member."
10410
+ },
10411
+ {
10412
+ "role": "patient",
10413
+ "label": "Patient",
10414
+ "inverseLabel": "Doctor",
10415
+ "description": "This person is a patient of the member."
10416
+ }
10417
+ ]
10418
+ },
10419
+ {
10420
+ "kind": "primary_contact_of",
10421
+ "cardinality": "one_per_target",
10422
+ "symmetric": false,
10423
+ "grantsChartAccess": true,
10424
+ "roles": [
10425
+ {
10426
+ "role": "primary_contact",
10427
+ "label": "Primary contact",
10428
+ "inverseLabel": "Primary contact for",
10429
+ "description": "This person is the organization's primary contact for the member. A member has at most one."
10430
+ },
10431
+ {
10432
+ "role": "primary_contact_for",
10433
+ "label": "Primary contact for",
10434
+ "inverseLabel": "Primary contact",
10435
+ "description": "The member is this person's assigned primary contact inside the organization."
10436
+ }
10437
+ ]
10438
+ }
10439
+ ];
10440
+
10441
+ // src/types/generated/ui_prompt.ts
10442
+ var UiPromptPresentedKind = {
10443
+ render_ui: "render_ui",
10444
+ present_choice_list: "present_choice_list",
10445
+ inline_connect: "inline_connect"
10446
+ };
10447
+ var UiPromptResponseKind = {
10448
+ render_ui: "render_ui",
10449
+ present_choice_list: "present_choice_list",
10450
+ inline_connect: "inline_connect"
10451
+ };
10452
+ var UiPromptResponseStatus = {
10453
+ submitted: "submitted",
10454
+ declined: "declined"
10455
+ };
10456
+
10457
+ // src/api/workspace-invitations.ts
10458
+ var WorkspaceInvitationsApi = class extends BaseApiClient {
10459
+ /**
10460
+ * List user's own invitations (both org and workspace).
10461
+ * For admin listing of a specific workspace's invitations, use listWorkspaceInvitationsAdmin.
10462
+ */
10463
+ async listWorkspaceInvitations(params) {
10464
+ const queryParams = new URLSearchParams();
10465
+ if (params?.status) queryParams.append("status", params.status);
10466
+ if (params?.page) queryParams.append("page", params.page.toString());
10467
+ if (params?.pageSize) queryParams.append("page_size", params.pageSize.toString());
10468
+ const queryString = queryParams.toString();
10469
+ const url = `invitations${queryString ? `?${queryString}` : ""}`;
10470
+ return this.fetch(url);
10471
+ }
9745
10472
  async getWorkspaceInvitation(requestId) {
9746
10473
  return this.fetch(`invitations/${requestId}`);
9747
10474
  }
@@ -9862,11 +10589,31 @@ var WorkspaceInvitationsApi = class extends BaseApiClient {
9862
10589
  };
9863
10590
 
9864
10591
  // src/api/workspaces.ts
10592
+ function planFields(options) {
10593
+ if (!options) return {};
10594
+ const fields = {};
10595
+ if (options.intent !== void 0) fields.intent = options.intent;
10596
+ if (options.expectedPlanFingerprint !== void 0) {
10597
+ fields.expectedPlanFingerprint = options.expectedPlanFingerprint;
10598
+ }
10599
+ if (options.bindings !== void 0 && options.bindings.length > 0) {
10600
+ fields.bindings = options.bindings;
10601
+ }
10602
+ return fields;
10603
+ }
9865
10604
  var WorkspacesApi = class extends BaseApiClient {
9866
10605
  /** List all workspaces accessible to the current user. */
9867
10606
  async getWorkspaces() {
9868
10607
  return this.fetch("w/");
9869
10608
  }
10609
+ /**
10610
+ * Compact rows for the workspaces a companion device could enter — the
10611
+ * Lantern picker. Filtered by the same admission policy a device
10612
+ * credential is gated by, without needing the device credential.
10613
+ */
10614
+ async getDeviceAdmissibleWorkspaces() {
10615
+ return this.fetch("w/?can_use_device=1");
10616
+ }
9870
10617
  /** List all publicly visible workspaces. */
9871
10618
  async getPublicWorkspaces() {
9872
10619
  return this.fetch("w/public");
@@ -10160,18 +10907,62 @@ var WorkspacesApi = class extends BaseApiClient {
10160
10907
  const qs = searchParams.toString();
10161
10908
  return this.fetch(`w/${wid}/export${qs ? `?${qs}` : ""}`);
10162
10909
  }
10163
- /** Preview the result of importing workspace configuration without applying changes. */
10164
- async previewWorkspaceImport(wid, exportData, importMappings, createNew, autoMap) {
10910
+ /** Preview the result of importing workspace configuration without applying changes.
10911
+ *
10912
+ * Pass `options.intent = 'template_reapply'` to get the deterministic
10913
+ * re-apply plan: `planRows`, `sourceFingerprint` and `planFingerprint` come
10914
+ * back beside the legacy preview items, and the fingerprint is what
10915
+ * `importWorkspace` must be given to apply exactly that projection.
10916
+ */
10917
+ async previewWorkspaceImport(wid, exportData, importMappings, createNew, autoMap, options) {
10165
10918
  return this.fetch(`w/${wid}/preview-import`, {
10166
10919
  method: "POST",
10167
10920
  body: JSON.stringify({
10168
10921
  exportData,
10169
10922
  importMappings,
10170
10923
  createNew,
10171
- autoMap
10924
+ autoMap,
10925
+ ...planFields(options)
10172
10926
  })
10173
10927
  });
10174
10928
  }
10929
+ /**
10930
+ * Plan a workspace export ZIP against this workspace without importing it.
10931
+ *
10932
+ * The sibling of `previewWorkspaceImport`, and it exists for one reason: a
10933
+ * JSON preview has no archive, so it cannot decide whether File BYTES would
10934
+ * be replaced — that decision compares the archive's blob digest against the
10935
+ * destination's current content digest.
10936
+ */
10937
+ async previewWorkspaceImportZip(wid, archive, options) {
10938
+ const { exportData, importMappings, createNew, autoMap, ...planOptions } = options ?? {};
10939
+ const payload = {
10940
+ importMappings: importMappings ?? {},
10941
+ createNew: createNew ?? {},
10942
+ ...planFields(planOptions)
10943
+ };
10944
+ if (exportData) payload.exportData = exportData;
10945
+ if (autoMap) payload.autoMap = autoMap;
10946
+ const form = new FormData();
10947
+ form.append(
10948
+ "request",
10949
+ new Blob([JSON.stringify(payload)], { type: "application/json" }),
10950
+ "import.json"
10951
+ );
10952
+ form.append("archive", archive, "workspace-export.zip");
10953
+ return this.fetch(`w/${wid}/preview-import.zip`, {
10954
+ method: "POST",
10955
+ body: form
10956
+ });
10957
+ }
10958
+ /**
10959
+ * Everything a template re-apply adds to an import or a preview.
10960
+ *
10961
+ * `bindings` values are sent in the request body only. They are never
10962
+ * projected from a response and must never be logged: the point of a
10963
+ * binding is that a webhook endpoint and a signing secret belong to ONE
10964
+ * target workspace.
10965
+ */
10175
10966
  /** Download a workspace export ZIP (``export.json`` + file blobs). */
10176
10967
  async exportWorkspaceZip(wid, workflowId, scope, exclude) {
10177
10968
  const searchParams = new URLSearchParams();
@@ -10185,46 +10976,138 @@ var WorkspacesApi = class extends BaseApiClient {
10185
10976
  /** Import workspace configuration from exported JSON, or from a ZIP archive.
10186
10977
  * Pass ``archive`` (the ZIP from ``exportWorkspaceZip``) to restore file
10187
10978
  * contents. ``exportData`` may be omitted when the ZIP contains it.
10188
- */
10189
- async importWorkspace(wid, exportData, importMappings, createNew, archive) {
10190
- const payload = {
10191
- importMappings,
10192
- createNew
10193
- };
10194
- if (exportData) {
10195
- payload.exportData = exportData;
10196
- }
10979
+ *
10980
+ * ``activateWebhookRules`` is safety-default false: imported
10981
+ * ``webhook:send`` EventRules are force-disabled unless the operator
10982
+ * opts in. An exported-inactive rule stays inactive either way.
10983
+ *
10984
+ * With ``options.intent = 'template_reapply'`` this is the GUARDED apply.
10985
+ * It requires ``options.expectedPlanFingerprint`` — the digest a preview
10986
+ * returned — and answers 200 ``success``, 200 ``noop`` (the target already
10987
+ * matched the template, so nothing at all was recorded), 409
10988
+ * ``stale_import_plan`` or 409 ``import_plan_refused``. Both 409s commit
10989
+ * nothing and carry the complete values-free ``planRows``.
10990
+ */
10991
+ async importWorkspace(wid, exportData, importMappings, createNew, archive, activateWebhookRules, autoMap, options) {
10197
10992
  if (archive) {
10198
- const form = new FormData();
10199
- form.append(
10200
- "request",
10201
- new Blob([JSON.stringify(payload)], { type: "application/json" }),
10202
- "import.json"
10203
- );
10204
- form.append("archive", archive, "workspace-export.zip");
10205
- return this.fetch(`w/${wid}/import.zip`, {
10206
- method: "POST",
10207
- body: form
10993
+ return this.importWorkspaceZip(wid, archive, {
10994
+ ...options,
10995
+ exportData,
10996
+ importMappings,
10997
+ createNew,
10998
+ autoMap,
10999
+ activateWebhookRules
10208
11000
  });
10209
11001
  }
10210
11002
  if (!exportData) {
10211
11003
  throw new Error("exportData is required for JSON import");
10212
11004
  }
11005
+ const payload = {
11006
+ exportData,
11007
+ importMappings,
11008
+ createNew,
11009
+ ...planFields(options)
11010
+ };
11011
+ if (activateWebhookRules) {
11012
+ payload.activateWebhookRules = activateWebhookRules;
11013
+ }
11014
+ if (autoMap) {
11015
+ payload.autoMap = autoMap;
11016
+ }
10213
11017
  return this.fetch(`w/${wid}/import`, {
10214
11018
  method: "POST",
10215
11019
  body: JSON.stringify(payload)
10216
11020
  });
10217
11021
  }
11022
+ /**
11023
+ * Apply a workspace export ZIP to this workspace.
11024
+ *
11025
+ * The apply sibling of `previewWorkspaceImportZip`, and the same multipart
11026
+ * shape: the archive travels as `archive`, everything else as one JSON
11027
+ * `request` part. `exportData` defaults to `export.json` inside the ZIP, so
11028
+ * it is sent only to override it.
11029
+ *
11030
+ * With `options.intent = 'template_reapply'` this is the GUARDED apply. It
11031
+ * requires `options.expectedPlanFingerprint` — the digest a preview
11032
+ * returned — and answers 200 `success`, 200 `noop` (the target already
11033
+ * matched the template, so nothing at all was recorded), 409
11034
+ * `stale_import_plan` or 409 `import_plan_refused`. Both 409s commit
11035
+ * nothing and carry the complete values-free `planRows`.
11036
+ *
11037
+ * `options.bindings` values are sent in the request body only. They are
11038
+ * never projected from a response and must never be logged: the point of a
11039
+ * binding is that a webhook endpoint and a signing secret belong to ONE
11040
+ * target workspace.
11041
+ */
11042
+ async importWorkspaceZip(wid, archive, options) {
11043
+ const {
11044
+ exportData,
11045
+ importMappings,
11046
+ createNew,
11047
+ autoMap,
11048
+ activateWebhookRules,
11049
+ ...planOptions
11050
+ } = options ?? {};
11051
+ const payload = {
11052
+ importMappings: importMappings ?? {},
11053
+ createNew: createNew ?? {},
11054
+ ...planFields(planOptions)
11055
+ };
11056
+ if (exportData) payload.exportData = exportData;
11057
+ if (activateWebhookRules) payload.activateWebhookRules = activateWebhookRules;
11058
+ if (autoMap) payload.autoMap = autoMap;
11059
+ const form = new FormData();
11060
+ form.append(
11061
+ "request",
11062
+ new Blob([JSON.stringify(payload)], { type: "application/json" }),
11063
+ "import.json"
11064
+ );
11065
+ form.append("archive", archive, "workspace-export.zip");
11066
+ return this.fetch(`w/${wid}/import.zip`, {
11067
+ method: "POST",
11068
+ body: form
11069
+ });
11070
+ }
11071
+ /**
11072
+ * Reconnectable EventRules skipped by the latest workspace import, grouped
11073
+ * by the missing phone / inbox / member. Templates and action params are
11074
+ * not returned.
11075
+ */
11076
+ async getImportSkippedRules(wid, status) {
11077
+ const params = new URLSearchParams();
11078
+ if (status !== void 0) {
11079
+ params.set("status", status);
11080
+ }
11081
+ const qs = params.toString();
11082
+ return this.fetch(
11083
+ `w/${wid}/import/skipped-rules${qs ? `?${qs}` : ""}`
11084
+ );
11085
+ }
11086
+ /** Current bounded phone, inbox, and phone-chat binding gaps after an import. */
11087
+ async getImportReadiness(wid) {
11088
+ return this.fetch(`w/${wid}/import/readiness`);
11089
+ }
11090
+ /**
11091
+ * Re-point every outstanding skipped EventRule that needed the same source
11092
+ * resource onto a re-provisioned one, recreating each rule from its
11093
+ * preserved definition. Repeat calls no-op on already-reconnected rows.
11094
+ */
11095
+ async rebuildImportSkippedRules(wid, body) {
11096
+ return this.fetch(
11097
+ `w/${wid}/import/skipped-rules/rebuild`,
11098
+ { method: "POST", body: JSON.stringify(body) }
11099
+ );
11100
+ }
10218
11101
  /** Preview a workspace import using the legacy untyped interface. */
10219
11102
  // Legacy method for backward compatibility
10220
- async previewImportWorkspace(wid, exportData, importMappings = {}, createNew = {}) {
11103
+ async previewImportWorkspace(wid, exportData, importMappings = {}, createNew = {}, autoMap) {
11104
+ const payload = { exportData, importMappings, createNew };
11105
+ if (autoMap) {
11106
+ payload.autoMap = autoMap;
11107
+ }
10221
11108
  return this.fetch(`w/${wid}/preview-import`, {
10222
11109
  method: "POST",
10223
- body: JSON.stringify({
10224
- exportData,
10225
- importMappings,
10226
- createNew
10227
- })
11110
+ body: JSON.stringify(payload)
10228
11111
  });
10229
11112
  }
10230
11113
  /** List available themes for a workspace. */
@@ -10372,7 +11255,7 @@ function createApiModules(apiKey, baseUrl, customFetch) {
10372
11255
  connectionSync: new ConnectionSyncApi(apiKey, baseUrl, customFetch),
10373
11256
  mcpServers: new McpServersApi(apiKey, baseUrl, customFetch),
10374
11257
  members: new MembersApi(apiKey, baseUrl, customFetch),
10375
- activityTimeline: new ActivityTimelineApi(apiKey, baseUrl, customFetch),
11258
+ activity: new ActivityApi(apiKey, baseUrl, customFetch),
10376
11259
  motd: new MotdApi(apiKey, baseUrl, customFetch),
10377
11260
  trackedLinks: new TrackedLinksApi(apiKey, baseUrl, customFetch),
10378
11261
  confluence: new ConfluenceApi(apiKey, baseUrl, customFetch),
@@ -10419,6 +11302,8 @@ var WORKSPACE_METHOD_NAMES = [
10419
11302
  "archiveDataType",
10420
11303
  "archiveJourney",
10421
11304
  "archiveMember",
11305
+ "archiveMemberRelationship",
11306
+ "archivePersona",
10422
11307
  "archivePhoneNumber",
10423
11308
  "archiveStep",
10424
11309
  "archiveTask",
@@ -10471,6 +11356,8 @@ var WORKSPACE_METHOD_NAMES = [
10471
11356
  "createCalendarEventType",
10472
11357
  "createCalendarSchedule",
10473
11358
  "createChat",
11359
+ "createChatInteractionSession",
11360
+ "transitionChatInteractionSession",
10474
11361
  "createChatCompletion",
10475
11362
  "createChatFilter",
10476
11363
  "createChatLabel",
@@ -10500,6 +11387,7 @@ var WORKSPACE_METHOD_NAMES = [
10500
11387
  "createMemberFilter",
10501
11388
  "createMemberLabel",
10502
11389
  "createMemberMemory",
11390
+ "createMemberRelationship",
10503
11391
  "createMemberRole",
10504
11392
  "createMenuItem",
10505
11393
  "createNotificationRule",
@@ -10602,7 +11490,6 @@ var WORKSPACE_METHOD_NAMES = [
10602
11490
  "disconnectConfluence",
10603
11491
  "disconnectHubspot",
10604
11492
  "disconnectMondayConnection",
10605
- "disconnectPresence",
10606
11493
  "disconnectSalesforce",
10607
11494
  "discordLinkPreflight",
10608
11495
  "discoverOAuthMetadata",
@@ -10665,6 +11552,7 @@ var WORKSPACE_METHOD_NAMES = [
10665
11552
  "getAccessGrant",
10666
11553
  "getAccessGrants",
10667
11554
  "getAgent",
11555
+ "getAgentModeAttention",
10668
11556
  "getAgentTask",
10669
11557
  "getAgentTaskMessages",
10670
11558
  "getAgentTasks",
@@ -10696,7 +11584,9 @@ var WORKSPACE_METHOD_NAMES = [
10696
11584
  "getCharlestonTestDeliveryRecipients",
10697
11585
  "getChat",
10698
11586
  "getChatAssignmentTasks",
11587
+ "getChatBrowserLiveView",
10699
11588
  "getChatCallbacks",
11589
+ "getChatEhrWritebackOutcomes",
10700
11590
  "getChatEmails",
10701
11591
  "getChatFilter",
10702
11592
  "getChatFilterByUuid",
@@ -10705,6 +11595,7 @@ var WORKSPACE_METHOD_NAMES = [
10705
11595
  "getChatLabel",
10706
11596
  "getChatLabelByUuid",
10707
11597
  "getChatLabels",
11598
+ "getChatMachineResources",
10708
11599
  "getChatMessages",
10709
11600
  "getChatModelOverride",
10710
11601
  "getChatPhoneCalls",
@@ -10745,6 +11636,8 @@ var WORKSPACE_METHOD_NAMES = [
10745
11636
  "getDataRecordFilters",
10746
11637
  "getDataRecords",
10747
11638
  "getDataType",
11639
+ "getDataTypeDraft",
11640
+ "getDataTypeVersions",
10748
11641
  "getDataTypeByUuid",
10749
11642
  "getDataTypeBySlug",
10750
11643
  "getDataTypes",
@@ -10788,9 +11681,15 @@ var WORKSPACE_METHOD_NAMES = [
10788
11681
  "listChatRecordings",
10789
11682
  "previewQuery",
10790
11683
  "publishSiteSource",
10791
- "queryActivityTimeline",
11684
+ "publishDataTypeDraft",
11685
+ "saveDataTypeDraft",
11686
+ "queryWorkspaceActivity",
11687
+ "queryWorkspaceActivityLatestSubjects",
11688
+ "queryWorkspaceActivityOpenItems",
11689
+ "queryWorkspaceActivityOneView",
10792
11690
  "registerDiscordSlashCommands",
10793
11691
  "reopenWorkspaceSupportRequest",
11692
+ "resolveEntityRefs",
10794
11693
  "resetSiteSource",
10795
11694
  "resolveFilePath",
10796
11695
  "getFileLabel",
@@ -10818,16 +11717,22 @@ var WORKSPACE_METHOD_NAMES = [
10818
11717
  "getHubspotSyncLogs",
10819
11718
  "getHubspotTransformPresets",
10820
11719
  "getICalFeedUrl",
11720
+ "getImportSkippedRules",
11721
+ "getImportReadiness",
11722
+ "rebuildImportSkippedRules",
10821
11723
  "getInbox",
10822
11724
  "getInboxEmail",
10823
11725
  "getInboxEmails",
10824
11726
  "getInboxThreads",
10825
11727
  "getInboxes",
11728
+ "getInterventionRequests",
10826
11729
  "getJourney",
10827
11730
  "getJourneyAuthoring",
11731
+ "getJourneyFilterOptions",
10828
11732
  "getJourneyHealth",
10829
11733
  "getJourneyMembers",
10830
11734
  "getJourneyNotes",
11735
+ "getJourneyV2Validation",
10831
11736
  "getJourneys",
10832
11737
  "getLinkablePhones",
10833
11738
  "getLinkedHealthieMembers",
@@ -10855,6 +11760,7 @@ var WORKSPACE_METHOD_NAMES = [
10855
11760
  "getMemberMemories",
10856
11761
  "getMemberMemory",
10857
11762
  "getMemberRecordCounts",
11763
+ "getMemberRelationships",
10858
11764
  "getMemberRole",
10859
11765
  "getMemberRoleCleanupPlan",
10860
11766
  "getMemberRoleByUuid",
@@ -10903,8 +11809,6 @@ var WORKSPACE_METHOD_NAMES = [
10903
11809
  "getPublicFolder",
10904
11810
  "getPublicFolderFiles",
10905
11811
  "getPublicProducts",
10906
- "previewPromoCode",
10907
- "startPromoPlanTrial",
10908
11812
  "getQualification",
10909
11813
  "getQualifications",
10910
11814
  "getRecordingInfo",
@@ -10959,10 +11863,10 @@ var WORKSPACE_METHOD_NAMES = [
10959
11863
  "getUnreadNotificationCount",
10960
11864
  "getUsageDashboard",
10961
11865
  "getVariableRegistry",
10962
- "getVoiceToken",
10963
11866
  "getVoiceUsageReport",
10964
11867
  "getWebhookLogs",
10965
11868
  "getWorkflow",
11869
+ "getWorkflowOpeningTurnConversionReport",
10966
11870
  "getWorkflowAccessValidation",
10967
11871
  "getWorkflowActivity",
10968
11872
  "getWorkflowConfigValidation",
@@ -10979,6 +11883,7 @@ var WORKSPACE_METHOD_NAMES = [
10979
11883
  "getWorkflows",
10980
11884
  "getWorkflowsActivityBatch",
10981
11885
  "getWorkspace",
11886
+ "getWorkspaceActivityCounts",
10982
11887
  "getWorkspaceBuilder",
10983
11888
  "getWorkspaceBuilders",
10984
11889
  "getWorkspaceCounts",
@@ -10998,7 +11903,7 @@ var WORKSPACE_METHOD_NAMES = [
10998
11903
  "importMembers",
10999
11904
  "importSalesforceMembers",
11000
11905
  "importWorkspace",
11001
- "initiateCall",
11906
+ "importWorkspaceZip",
11002
11907
  "initiateOutboundCall",
11003
11908
  "inspectPrompt",
11004
11909
  "installHubspot",
@@ -11055,14 +11960,17 @@ var WORKSPACE_METHOD_NAMES = [
11055
11960
  "previewMemberWorkflowVoice",
11056
11961
  "previewRenameFieldSlug",
11057
11962
  "previewImportWorkspace",
11963
+ "previewRoutineVoiceReadiness",
11058
11964
  "previewRoutineWorkflowAccess",
11059
11965
  "previewSchedule",
11060
11966
  "previewTTS",
11061
11967
  "previewTemplate",
11062
11968
  "previewThinkingSound",
11063
11969
  "previewWorkspaceImport",
11970
+ "previewWorkspaceImportZip",
11064
11971
  "provisionClientWorkspace",
11065
11972
  "publishWorkflowRevision",
11973
+ "putJourneyV2Definition",
11066
11974
  "rateMessage",
11067
11975
  "getChatFeedback",
11068
11976
  "reenrollMember",
@@ -11083,6 +11991,7 @@ var WORKSPACE_METHOD_NAMES = [
11083
11991
  "resetRoutineRuns",
11084
11992
  "resolveAccessGrant",
11085
11993
  "resolveAnonymousMember",
11994
+ "resolveInterventionRequest",
11086
11995
  "restoreFileVersion",
11087
11996
  "revokeAccessGrant",
11088
11997
  "revokeApiKey",
@@ -11123,6 +12032,7 @@ var WORKSPACE_METHOD_NAMES = [
11123
12032
  "unarchiveChat",
11124
12033
  "unarchiveDataType",
11125
12034
  "unarchiveMember",
12035
+ "unarchivePersona",
11126
12036
  "unarchiveStep",
11127
12037
  "unarchiveTask",
11128
12038
  "unarchiveWorkflow",
@@ -11211,6 +12121,7 @@ var WORKSPACE_METHOD_NAMES = [
11211
12121
  "uploadFile",
11212
12122
  "updateVoicemailStatus",
11213
12123
  "updateWorkflow",
12124
+ "convertWorkflowStartTaskOpeningMessage",
11214
12125
  "updateWorkflowContributor",
11215
12126
  "updateWorkflowNote",
11216
12127
  "updateWorkflowRevisionMetadata",
@@ -11257,6 +12168,13 @@ function bindAccessGrantsMethods(target, accessGrants) {
11257
12168
  target.getGranteeGrants = accessGrants.getGranteeGrants.bind(accessGrants);
11258
12169
  }
11259
12170
 
12171
+ // src/client/bindings/intervention-requests.ts
12172
+ function bindInterventionRequestsMethods(target, interventionRequests) {
12173
+ target.getAgentModeAttention = interventionRequests.getAgentModeAttention.bind(interventionRequests);
12174
+ target.getInterventionRequests = interventionRequests.getInterventionRequests.bind(interventionRequests);
12175
+ target.resolveInterventionRequest = interventionRequests.resolveInterventionRequest.bind(interventionRequests);
12176
+ }
12177
+
11260
12178
  // src/client/bindings/agent-tasks.ts
11261
12179
  function bindAgentTasksMethods(target, api) {
11262
12180
  target.getAgentTasks = api.getAgentTasks.bind(api);
@@ -11297,10 +12215,15 @@ function bindTasksMethods(target, tasks, abilities) {
11297
12215
 
11298
12216
  // src/client/bindings/chats.ts
11299
12217
  function bindChatsMethods(target, chats) {
12218
+ target.createChatInteractionSession = chats.createChatInteractionSession.bind(chats);
12219
+ target.transitionChatInteractionSession = chats.transitionChatInteractionSession.bind(chats);
11300
12220
  target.getChats = chats.getChats.bind(chats);
11301
12221
  target.getChat = chats.getChat.bind(chats);
12222
+ target.getChatBrowserLiveView = chats.getChatBrowserLiveView.bind(chats);
12223
+ target.getChatMachineResources = chats.getChatMachineResources.bind(chats);
11302
12224
  target.getCurrentSmsChat = chats.getCurrentSmsChat.bind(chats);
11303
12225
  target.getChatCallbacks = chats.getChatCallbacks.bind(chats);
12226
+ target.getChatEhrWritebackOutcomes = chats.getChatEhrWritebackOutcomes.bind(chats);
11304
12227
  target.cancelChatCallback = chats.cancelChatCallback.bind(chats);
11305
12228
  target.getChatTokenUsage = chats.getChatTokenUsage.bind(chats);
11306
12229
  target.getChatTodos = chats.getChatTodos.bind(chats);
@@ -11353,8 +12276,6 @@ function bindChatsMethods(target, chats) {
11353
12276
  // src/client/bindings/calls.ts
11354
12277
  function bindCallsMethods(target, calls, cel) {
11355
12278
  target.getPhoneCalls = calls.getPhoneCalls.bind(calls);
11356
- target.initiateCall = calls.initiateCall.bind(calls);
11357
- target.getVoiceToken = calls.getVoiceToken.bind(calls);
11358
12279
  target.getMessageTiming = calls.getMessageTiming.bind(calls);
11359
12280
  target.getRecordingInfo = calls.getRecordingInfo.bind(calls);
11360
12281
  target.listChatRecordings = calls.listChatRecordings.bind(calls);
@@ -11375,9 +12296,25 @@ function bindDashboardsMethods(target, dashboards) {
11375
12296
  target.getConfigurationHealth = dashboards.getConfigurationHealth.bind(dashboards);
11376
12297
  }
11377
12298
 
11378
- // src/client/bindings/activity-timeline.ts
11379
- function bindActivityTimelineMethods(target, activityTimeline) {
11380
- target.queryActivityTimeline = activityTimeline.queryActivityTimeline.bind(activityTimeline);
12299
+ // src/client/bindings/activity.ts
12300
+ function bindActivityMethods(target, activity) {
12301
+ target.queryActivity = activity.queryActivity.bind(activity);
12302
+ target.queryActivityLatestSubjects = activity.queryActivityLatestSubjects.bind(activity);
12303
+ target.queryActivityOpenItems = activity.queryActivityOpenItems.bind(activity);
12304
+ target.queryActivityOneView = activity.queryActivityOneView.bind(activity);
12305
+ target.getActivityCounts = activity.getActivityCounts.bind(activity);
12306
+ target.getActivityCapabilities = activity.getActivityCapabilities.bind(activity);
12307
+ target.queryOrgActivity = activity.queryOrgActivity.bind(activity);
12308
+ target.queryOrgActivityLatestSubjects = activity.queryOrgActivityLatestSubjects.bind(activity);
12309
+ target.queryOrgActivityOpenItems = activity.queryOrgActivityOpenItems.bind(activity);
12310
+ target.queryOrgActivityOneView = activity.queryOrgActivityOneView.bind(activity);
12311
+ target.getOrgActivityCounts = activity.getOrgActivityCounts.bind(activity);
12312
+ target.queryWorkspaceActivity = activity.queryWorkspaceActivity.bind(activity);
12313
+ target.queryWorkspaceActivityLatestSubjects = activity.queryWorkspaceActivityLatestSubjects.bind(activity);
12314
+ target.queryWorkspaceActivityOpenItems = activity.queryWorkspaceActivityOpenItems.bind(activity);
12315
+ target.queryWorkspaceActivityOneView = activity.queryWorkspaceActivityOneView.bind(activity);
12316
+ target.getWorkspaceActivityCounts = activity.getWorkspaceActivityCounts.bind(activity);
12317
+ target.resolveEntityRefs = activity.resolveEntityRefs.bind(activity);
11381
12318
  }
11382
12319
 
11383
12320
  // src/client/bindings/motd.ts
@@ -11399,6 +12336,10 @@ function bindTrackedLinksMethods(target, trackedLinks) {
11399
12336
 
11400
12337
  // src/client/bindings/data-types.ts
11401
12338
  function bindDataTypesMethods(target, dataTypes) {
12339
+ target.getDataTypeDraft = dataTypes.getDataTypeDraft.bind(dataTypes);
12340
+ target.saveDataTypeDraft = dataTypes.saveDataTypeDraft.bind(dataTypes);
12341
+ target.publishDataTypeDraft = dataTypes.publishDataTypeDraft.bind(dataTypes);
12342
+ target.getDataTypeVersions = dataTypes.getDataTypeVersions.bind(dataTypes);
11402
12343
  target.getDataTypes = dataTypes.getDataTypes.bind(dataTypes);
11403
12344
  target.getDataType = dataTypes.getDataType.bind(dataTypes);
11404
12345
  target.getDataTypeByUuid = dataTypes.getDataTypeByUuid.bind(dataTypes);
@@ -11484,6 +12425,8 @@ function bindMembersMethods(target, members) {
11484
12425
  target.createMemberRole = members.createMemberRole.bind(members);
11485
12426
  target.updateMemberRole = members.updateMemberRole.bind(members);
11486
12427
  target.deleteMemberRole = members.deleteMemberRole.bind(members);
12428
+ target.getMemberRoleCleanupPlan = members.getMemberRoleCleanupPlan.bind(members);
12429
+ target.mergeMemberRoles = members.mergeMemberRoles.bind(members);
11487
12430
  target.getMemberFields = members.getMemberFields.bind(members);
11488
12431
  target.getMemberFieldDefinitions = members.getMemberFieldDefinitions.bind(members);
11489
12432
  target.createMemberField = members.createMemberField.bind(members);
@@ -11501,11 +12444,15 @@ function bindMembersMethods(target, members) {
11501
12444
  target.createMemberMemory = members.createMemberMemory.bind(members);
11502
12445
  target.deleteMemberMemory = members.deleteMemberMemory.bind(members);
11503
12446
  target.getMemberSyncLinks = members.getMemberSyncLinks.bind(members);
12447
+ target.getMemberRelationships = members.getMemberRelationships.bind(members);
12448
+ target.createMemberRelationship = members.createMemberRelationship.bind(members);
12449
+ target.archiveMemberRelationship = members.archiveMemberRelationship.bind(members);
11504
12450
  }
11505
12451
 
11506
12452
  // src/client/bindings/workspaces.ts
11507
12453
  function bindWorkspacesMethods(target, workspaces, signupRequests) {
11508
12454
  target.getWorkspaces = workspaces.getWorkspaces.bind(workspaces);
12455
+ target.getDeviceAdmissibleWorkspaces = workspaces.getDeviceAdmissibleWorkspaces.bind(workspaces);
11509
12456
  target.getPublicWorkspaces = workspaces.getPublicWorkspaces.bind(workspaces);
11510
12457
  target.getWorkspace = workspaces.getWorkspace.bind(workspaces);
11511
12458
  target.createWorkspace = workspaces.createWorkspace.bind(workspaces);
@@ -11536,6 +12483,8 @@ function bindWorkspacesMethods(target, workspaces, signupRequests) {
11536
12483
  target.getProduct = workspaces.getProduct.bind(workspaces);
11537
12484
  target.getWorkspaceProduct = workspaces.getWorkspaceProduct.bind(workspaces);
11538
12485
  target.getPublicProducts = workspaces.getPublicProducts.bind(workspaces);
12486
+ target.previewPromoCode = workspaces.previewPromoCode.bind(workspaces);
12487
+ target.startPromoPlanTrial = workspaces.startPromoPlanTrial.bind(workspaces);
11539
12488
  target.getPublicProduct = workspaces.getPublicProduct.bind(workspaces);
11540
12489
  target.createProduct = workspaces.createProduct.bind(workspaces);
11541
12490
  target.updateProduct = workspaces.updateProduct.bind(workspaces);
@@ -11543,7 +12492,12 @@ function bindWorkspacesMethods(target, workspaces, signupRequests) {
11543
12492
  target.exportWorkspace = workspaces.exportWorkspace.bind(workspaces);
11544
12493
  target.exportWorkspaceZip = workspaces.exportWorkspaceZip.bind(workspaces);
11545
12494
  target.previewWorkspaceImport = workspaces.previewWorkspaceImport.bind(workspaces);
12495
+ target.previewWorkspaceImportZip = workspaces.previewWorkspaceImportZip.bind(workspaces);
11546
12496
  target.importWorkspace = workspaces.importWorkspace.bind(workspaces);
12497
+ target.importWorkspaceZip = workspaces.importWorkspaceZip.bind(workspaces);
12498
+ target.getImportSkippedRules = workspaces.getImportSkippedRules.bind(workspaces);
12499
+ target.getImportReadiness = workspaces.getImportReadiness.bind(workspaces);
12500
+ target.rebuildImportSkippedRules = workspaces.rebuildImportSkippedRules.bind(workspaces);
11547
12501
  target.previewImportWorkspace = workspaces.previewImportWorkspace.bind(workspaces);
11548
12502
  target.getWorkspaceThemes = workspaces.getWorkspaceThemes.bind(workspaces);
11549
12503
  target.updateWorkspaceThemes = workspaces.updateWorkspaceThemes.bind(workspaces);
@@ -11751,9 +12705,11 @@ function bindEventsMethods(target, events) {
11751
12705
  target.updateRoutine = events.updateRoutine.bind(events);
11752
12706
  target.deleteRoutine = events.deleteRoutine.bind(events);
11753
12707
  target.runRoutine = events.runRoutine.bind(events);
12708
+ target.getRoutineConfigEvents = events.getRoutineConfigEvents.bind(events);
11754
12709
  target.getRoutineRuns = events.getRoutineRuns.bind(events);
11755
12710
  target.resetRoutineRuns = events.resetRoutineRuns.bind(events);
11756
12711
  target.previewSchedule = events.previewSchedule.bind(events);
12712
+ target.previewRoutineVoiceReadiness = events.previewRoutineVoiceReadiness.bind(events);
11757
12713
  target.previewRoutineWorkflowAccess = events.previewRoutineWorkflowAccess.bind(events);
11758
12714
  }
11759
12715
 
@@ -11778,6 +12734,8 @@ function bindExperimentsMethods(target, experiments) {
11778
12734
  function bindWorkflowsMethods(target, workflows, workflowNotes, voice, supervisors) {
11779
12735
  target.getWorkflows = workflows.getWorkflows.bind(workflows);
11780
12736
  target.getWorkflow = workflows.getWorkflow.bind(workflows);
12737
+ target.getWorkflowOpeningTurnConversionReport = workflows.getWorkflowOpeningTurnConversionReport.bind(workflows);
12738
+ target.convertWorkflowStartTaskOpeningMessage = workflows.convertWorkflowStartTaskOpeningMessage.bind(workflows);
11781
12739
  target.getWorkflowActivity = workflows.getWorkflowActivity.bind(workflows);
11782
12740
  target.getWorkflowsActivityBatch = workflows.getWorkflowsActivityBatch.bind(workflows);
11783
12741
  target.getWorkflowDiagram = workflows.getWorkflowDiagram.bind(workflows);
@@ -12198,7 +13156,6 @@ function bindOperatorMethods(target, operatorGroups) {
12198
13156
  target.removeGroupMember = operatorGroups.removeGroupMember.bind(operatorGroups);
12199
13157
  target.getLiveOperators = operatorGroups.getLiveOperators.bind(operatorGroups);
12200
13158
  target.getPresenceStatus = operatorGroups.getPresenceStatus.bind(operatorGroups);
12201
- target.disconnectPresence = operatorGroups.disconnectPresence.bind(operatorGroups);
12202
13159
  target.getOperatorChatMessages = operatorGroups.getOperatorChatMessages.bind(operatorGroups);
12203
13160
  target.sendOperatorMessage = operatorGroups.sendOperatorMessage.bind(operatorGroups);
12204
13161
  }
@@ -12226,6 +13183,8 @@ function bindOrgMethods(target, org) {
12226
13183
  target.listLegalEntities = org.listLegalEntities.bind(org);
12227
13184
  target.getLegalEntity = org.getLegalEntity.bind(org);
12228
13185
  target.createLegalEntity = org.createLegalEntity.bind(org);
13186
+ target.getRegistrationDraft = org.getRegistrationDraft.bind(org);
13187
+ target.saveRegistrationDraft = org.saveRegistrationDraft.bind(org);
12229
13188
  target.getVoiceTrustProducts = org.getVoiceTrustProducts.bind(org);
12230
13189
  target.syncVoiceTrustProducts = org.syncVoiceTrustProducts.bind(org);
12231
13190
  target.createOrganizationWorkspace = org.createOrganizationWorkspace.bind(org);
@@ -12257,6 +13216,9 @@ function bindJourneysMethods(target, journeys) {
12257
13216
  target.getJourneys = journeys.getJourneys.bind(journeys);
12258
13217
  target.getJourney = journeys.getJourney.bind(journeys);
12259
13218
  target.getJourneyAuthoring = journeys.getJourneyAuthoring.bind(journeys);
13219
+ target.putJourneyV2Definition = journeys.putJourneyV2Definition.bind(journeys);
13220
+ target.getJourneyV2Validation = journeys.getJourneyV2Validation.bind(journeys);
13221
+ target.getJourneyFilterOptions = journeys.getJourneyFilterOptions.bind(journeys);
12260
13222
  target.getJourneyHealth = journeys.getJourneyHealth.bind(journeys);
12261
13223
  target.createJourney = journeys.createJourney.bind(journeys);
12262
13224
  target.updateJourney = journeys.updateJourney.bind(journeys);
@@ -12312,6 +13274,8 @@ function bindPersonasMethods(target, personas) {
12312
13274
  target.getPersona = personas.getPersona.bind(personas);
12313
13275
  target.createPersona = personas.createPersona.bind(personas);
12314
13276
  target.updatePersona = personas.updatePersona.bind(personas);
13277
+ target.archivePersona = personas.archivePersona.bind(personas);
13278
+ target.unarchivePersona = personas.unarchivePersona.bind(personas);
12315
13279
  target.deletePersona = personas.deletePersona.bind(personas);
12316
13280
  }
12317
13281
 
@@ -12411,8 +13375,11 @@ var GravityRailClient = class {
12411
13375
  // Chats API
12412
13376
  getChats;
12413
13377
  getChat;
13378
+ getChatBrowserLiveView;
13379
+ getChatMachineResources;
12414
13380
  getCurrentSmsChat;
12415
13381
  getChatCallbacks;
13382
+ getChatEhrWritebackOutcomes;
12416
13383
  cancelChatCallback;
12417
13384
  getChatTokenUsage;
12418
13385
  getChatTodos;
@@ -12424,6 +13391,8 @@ var GravityRailClient = class {
12424
13391
  archiveChat;
12425
13392
  unarchiveChat;
12426
13393
  createChat;
13394
+ createChatInteractionSession;
13395
+ transitionChatInteractionSession;
12427
13396
  createWorkflowOutboundVoiceChat;
12428
13397
  deleteChat;
12429
13398
  updateChat;
@@ -12462,8 +13431,6 @@ var GravityRailClient = class {
12462
13431
  getChatFilterCount;
12463
13432
  // Calls API
12464
13433
  getPhoneCalls;
12465
- initiateCall;
12466
- getVoiceToken;
12467
13434
  getMessageTiming;
12468
13435
  getRecordingInfo;
12469
13436
  listChatRecordings;
@@ -12472,6 +13439,10 @@ var GravityRailClient = class {
12472
13439
  validateCelExpression;
12473
13440
  // Data Types API
12474
13441
  getDataTypes;
13442
+ getDataTypeDraft;
13443
+ saveDataTypeDraft;
13444
+ publishDataTypeDraft;
13445
+ getDataTypeVersions;
12475
13446
  getDataType;
12476
13447
  getDataTypeByUuid;
12477
13448
  getDataTypeBySlug;
@@ -12567,6 +13538,10 @@ var GravityRailClient = class {
12567
13538
  deleteMemberMemory;
12568
13539
  // Member Sync Links
12569
13540
  getMemberSyncLinks;
13541
+ // Member Relationships
13542
+ getMemberRelationships;
13543
+ createMemberRelationship;
13544
+ archiveMemberRelationship;
12570
13545
  // Agent Tasks API (operator-facing async sub-agent inspection/cancel)
12571
13546
  getAgentTasks;
12572
13547
  getAgentTask;
@@ -12604,6 +13579,8 @@ var GravityRailClient = class {
12604
13579
  getPersona;
12605
13580
  createPersona;
12606
13581
  updatePersona;
13582
+ archivePersona;
13583
+ unarchivePersona;
12607
13584
  deletePersona;
12608
13585
  // Metrics API (customer-defined outcome metrics)
12609
13586
  listMetrics;
@@ -12623,8 +13600,26 @@ var GravityRailClient = class {
12623
13600
  getDashboardChannelStats;
12624
13601
  getDashboardWorkflowAssignmentStats;
12625
13602
  getConfigurationHealth;
12626
- // Activity Timeline API
12627
- queryActivityTimeline;
13603
+ // Activity Spine serving API — one query shape, three mounts
13604
+ // (docs/projects/active/activity-spine.md).
13605
+ queryActivity;
13606
+ queryActivityLatestSubjects;
13607
+ queryActivityOpenItems;
13608
+ queryActivityOneView;
13609
+ getActivityCounts;
13610
+ getActivityCapabilities;
13611
+ queryOrgActivity;
13612
+ queryOrgActivityLatestSubjects;
13613
+ queryOrgActivityOpenItems;
13614
+ queryOrgActivityOneView;
13615
+ getOrgActivityCounts;
13616
+ queryWorkspaceActivity;
13617
+ queryWorkspaceActivityLatestSubjects;
13618
+ queryWorkspaceActivityOpenItems;
13619
+ queryWorkspaceActivityOneView;
13620
+ getWorkspaceActivityCounts;
13621
+ // Hydration: typed refs in, display summaries out, one round trip.
13622
+ resolveEntityRefs;
12628
13623
  // MOTD API
12629
13624
  getMotd;
12630
13625
  // Tracked Links analytics (#10934)
@@ -12640,6 +13635,9 @@ var GravityRailClient = class {
12640
13635
  getJourneys;
12641
13636
  getJourney;
12642
13637
  getJourneyAuthoring;
13638
+ putJourneyV2Definition;
13639
+ getJourneyV2Validation;
13640
+ getJourneyFilterOptions;
12643
13641
  getJourneyHealth;
12644
13642
  createJourney;
12645
13643
  updateJourney;
@@ -12694,7 +13692,6 @@ var GravityRailClient = class {
12694
13692
  removeGroupMember;
12695
13693
  getLiveOperators;
12696
13694
  getPresenceStatus;
12697
- disconnectPresence;
12698
13695
  getOperatorChatMessages;
12699
13696
  sendOperatorMessage;
12700
13697
  // Access Grants API
@@ -12707,10 +13704,15 @@ var GravityRailClient = class {
12707
13704
  getAccessGrants;
12708
13705
  getMemberGrants;
12709
13706
  getGranteeGrants;
13707
+ // Intervention Requests API
13708
+ getAgentModeAttention;
13709
+ getInterventionRequests;
13710
+ resolveInterventionRequest;
12710
13711
  // Prompts API
12711
13712
  inspectPrompt;
12712
13713
  // Workspaces API
12713
13714
  getWorkspaces;
13715
+ getDeviceAdmissibleWorkspaces;
12714
13716
  getPublicWorkspaces;
12715
13717
  getWorkspace;
12716
13718
  createWorkspace;
@@ -12750,7 +13752,12 @@ var GravityRailClient = class {
12750
13752
  exportWorkspace;
12751
13753
  exportWorkspaceZip;
12752
13754
  previewWorkspaceImport;
13755
+ previewWorkspaceImportZip;
12753
13756
  importWorkspace;
13757
+ importWorkspaceZip;
13758
+ getImportSkippedRules;
13759
+ getImportReadiness;
13760
+ rebuildImportSkippedRules;
12754
13761
  previewImportWorkspace;
12755
13762
  getWorkspaceThemes;
12756
13763
  updateWorkspaceThemes;
@@ -12785,6 +13792,8 @@ var GravityRailClient = class {
12785
13792
  listLegalEntities;
12786
13793
  getLegalEntity;
12787
13794
  createLegalEntity;
13795
+ getRegistrationDraft;
13796
+ saveRegistrationDraft;
12788
13797
  getVoiceTrustProducts;
12789
13798
  syncVoiceTrustProducts;
12790
13799
  createOrganizationWorkspace;
@@ -12976,10 +13985,13 @@ var GravityRailClient = class {
12976
13985
  getRoutineRuns;
12977
13986
  resetRoutineRuns;
12978
13987
  previewSchedule;
13988
+ previewRoutineVoiceReadiness;
12979
13989
  previewRoutineWorkflowAccess;
12980
13990
  // Workflows API
12981
13991
  getWorkflows;
12982
13992
  getWorkflow;
13993
+ getWorkflowOpeningTurnConversionReport;
13994
+ convertWorkflowStartTaskOpeningMessage;
12983
13995
  getWorkflowActivity;
12984
13996
  getWorkflowsActivityBatch;
12985
13997
  getWorkflowDiagram;
@@ -13455,7 +14467,7 @@ var GravityRailClient = class {
13455
14467
  bindMetricsMethods(this, apis.metrics);
13456
14468
  bindQueriesMethods(this, apis.queries);
13457
14469
  bindDashboardsMethods(this, apis.dashboards);
13458
- bindActivityTimelineMethods(this, apis.activityTimeline);
14470
+ bindActivityMethods(this, apis.activity);
13459
14471
  bindMotdMethods(this, apis.motd);
13460
14472
  bindTrackedLinksMethods(this, apis.trackedLinks);
13461
14473
  bindJourneysMethods(this, apis.journeys);
@@ -13463,6 +14475,7 @@ var GravityRailClient = class {
13463
14475
  bindOperatorMethods(this, apis.operatorGroups);
13464
14476
  bindOrgMethods(this, apis.org);
13465
14477
  bindAccessGrantsMethods(this, apis.accessGrants);
14478
+ bindInterventionRequestsMethods(this, apis.interventionRequests);
13466
14479
  bindPromptsMethods(this, apis.prompts);
13467
14480
  bindWorkspacesMethods(this, apis.workspaces, apis.workspaceInvitations);
13468
14481
  bindAuthMethods(this, apis.auth, apis.assignments);
@@ -13659,6 +14672,19 @@ var WorkspaceBuilderResource = class {
13659
14672
  get isImplicit() {
13660
14673
  return false;
13661
14674
  }
14675
+ /**
14676
+ * True when `apply()` is safe — and required — to run against a resource
14677
+ * that was ADOPTED rather than created.
14678
+ *
14679
+ * False by default because most builders create only: re-running their
14680
+ * `apply()` on an existing resource would make a duplicate. Override it
14681
+ * when `apply()` is an idempotent full write keyed on stable identities,
14682
+ * which is the only way a re-run can express an EDIT (a removed goal, a
14683
+ * reordered timeline) rather than just an addition.
14684
+ */
14685
+ get appliesWhenExisting() {
14686
+ return false;
14687
+ }
13662
14688
  matchKey() {
13663
14689
  return void 0;
13664
14690
  }
@@ -14337,6 +15363,755 @@ function buildJourneyGoalPayload(goal) {
14337
15363
  ...goal.value !== void 0 ? { value: goal.value } : {}
14338
15364
  };
14339
15365
  }
15366
+ var V2RouteBuilder = class {
15367
+ constructor(name, options = {}) {
15368
+ this.name = name;
15369
+ this.options = options;
15370
+ }
15371
+ name;
15372
+ options;
15373
+ touches = [];
15374
+ /**
15375
+ * The DECISION RULE uuid. Adopted for the same reason an Ending's is:
15376
+ * `MemberJourneyStep.entry_decision_rule_id` points at this row with
15377
+ * `ON DELETE SET NULL`, so recreating it on a re-run would erase which arm
15378
+ * every already-routed enrollment is on — invisibly, since both rules
15379
+ * "exist" afterwards.
15380
+ */
15381
+ _ruleUuid;
15382
+ /** Append a touch to this arm. Order is call order. */
15383
+ touch(name, options = {}) {
15384
+ const touch = new V2TouchBuilder(name, options);
15385
+ this.touches.push(touch);
15386
+ return touch;
15387
+ }
15388
+ };
15389
+ var V2BranchBuilder = class {
15390
+ routes = [];
15391
+ /** Append a route. Declaration order is evaluation order. */
15392
+ route(name, options = {}) {
15393
+ const route = new V2RouteBuilder(name, options);
15394
+ this.routes.push(route);
15395
+ return route;
15396
+ }
15397
+ };
15398
+ var V2TouchBuilder = class {
15399
+ /**
15400
+ * The name is CANONICALIZED here, once, and everything downstream reads it:
15401
+ * the `key:<name>` address, the payload, adoption's name lookup, and the
15402
+ * uniqueness gate. The API trims it before storing
15403
+ * (`JourneyV2TouchInput`/`JourneyV2EndingInput` name validators), so a
15404
+ * builder holding `" Welcome "` would send an address for a name the server
15405
+ * does not have, fail to find its own step on the way back, and treat it as
15406
+ * new on the next run — archiving the live step and its history. One
15407
+ * representation at the boundary is the only way that cannot happen; a
15408
+ * second trim anywhere downstream would be a place for the two to drift.
15409
+ */
15410
+ constructor(name, options = {}) {
15411
+ this.options = options;
15412
+ this.name = name.trim();
15413
+ }
15414
+ options;
15415
+ rules = [];
15416
+ /** Filled in from the server's response so a re-run keeps this touch. */
15417
+ _uuid;
15418
+ /**
15419
+ * The exclusive branch that follows this touch, when it has one. A touch
15420
+ * carrying a branch gets NO ordinary outgoing connection: its routes are
15421
+ * the only way out, so touches declared after it are reached only by an arm
15422
+ * naming them in `continueAt`.
15423
+ */
15424
+ _branch;
15425
+ name;
15426
+ /**
15427
+ * Attach an exclusive branch after this touch, or return the existing one.
15428
+ *
15429
+ * Idempotent so a script can add routes in stages without accidentally
15430
+ * declaring two branches on one touch — which the server has no shape for,
15431
+ * since a touch owns exactly one ordered route set.
15432
+ */
15433
+ branch() {
15434
+ this._branch ??= new V2BranchBuilder();
15435
+ return this._branch;
15436
+ }
15437
+ /**
15438
+ * The request-local address this step answers to (plan §3.8 / phase 6).
15439
+ *
15440
+ * A saved step is addressed by its uuid; an unsaved one by a `key` derived
15441
+ * from its authored name. Deriving from the NAME rather than minting a
15442
+ * uuid4 keeps the payload stable across re-runs of the same script — a
15443
+ * fresh random key on every run would make the request differ from itself
15444
+ * for no reason, and the server's EventRule sync matches on the uuids the
15445
+ * payload carries. Names are already asserted unique within a journey,
15446
+ * which is what makes a name-derived key unique.
15447
+ *
15448
+ * {@link V2EndingBuilder} INHERITS this rather than deriving its own: an
15449
+ * Ending's anchor key and a touch's key land in one server-side namespace
15450
+ * (`stepKey` is one field), so two derivations that drifted would produce
15451
+ * two spellings of the same address and a goal would 404 on the one its
15452
+ * step was not sent under.
15453
+ *
15454
+ * Two steps of one name therefore answer to one address. {@link preflight}
15455
+ * is the first enforcement point and refuses it before any write, counting
15456
+ * touches and Endings together and comparing names trimmed, as the API
15457
+ * stores them. Without that gate the collision surfaces twice and both
15458
+ * times too late: the server rejects the definition PUT after `apply()` has
15459
+ * created the Journey, and {@link indexStoredByName} rejects the SECOND run
15460
+ * of a script whose two stored steps make `adopt()` a coin flip.
15461
+ */
15462
+ get _address() {
15463
+ return this._uuid ?? `key:${this.name}`;
15464
+ }
15465
+ /**
15466
+ * Re-attach the EventRule uuids the server already stores for this touch.
15467
+ *
15468
+ * Identity is the operator-set rule NAME. `.sendsSms(...)` does not require
15469
+ * one, so an unnamed rule falls back to its actionType — but ONLY when that
15470
+ * answer is 1:1: exactly one unnamed draft of that actionType here, and
15471
+ * exactly one stored rule of it left unclaimed there. Anything else throws.
15472
+ *
15473
+ * The ordinal-within-actionType fallback this replaces was not a weaker
15474
+ * identity, it was the wrong one. Inserting a new unnamed rule ABOVE an
15475
+ * existing same-type rule shifts every position by one, so the new rule
15476
+ * adopted the existing rule's uuid — taking over its delivery bookkeeping —
15477
+ * and the existing rule was written as brand new and archived. Nothing in
15478
+ * the payload showed it: both rules "exist" afterwards. When the script
15479
+ * cannot say which rule is which, the honest answer is to ask the author to
15480
+ * name them, not to guess by position.
15481
+ */
15482
+ adoptRuleUuids(serverRules) {
15483
+ const namedDrafts = this.rules.filter((draft) => !!draft.options.name);
15484
+ const storedByName = indexStoredByName(
15485
+ serverRules,
15486
+ new Set(namedDrafts.map((draft) => draft.options.name)),
15487
+ `touch '${this.name}'`,
15488
+ "action"
15489
+ );
15490
+ const claimed = /* @__PURE__ */ new Set();
15491
+ for (const draft of namedDrafts) {
15492
+ const match = storedByName.get(draft.options.name);
15493
+ if (!match) continue;
15494
+ draft.adoptedUuid = match.uuid;
15495
+ claimed.add(match);
15496
+ }
15497
+ const unnamedByActionType = /* @__PURE__ */ new Map();
15498
+ for (const draft of this.rules) {
15499
+ if (draft.options.name) continue;
15500
+ const actionType = String(draft.actionType);
15501
+ unnamedByActionType.set(actionType, [
15502
+ ...unnamedByActionType.get(actionType) ?? [],
15503
+ draft
15504
+ ]);
15505
+ }
15506
+ for (const [actionType, drafts] of unnamedByActionType) {
15507
+ const candidates = serverRules.filter(
15508
+ (rule) => String(rule.actionType) === actionType && !claimed.has(rule)
15509
+ );
15510
+ if (!candidates.length) continue;
15511
+ if (drafts.length === 1 && candidates.length === 1) {
15512
+ drafts[0].adoptedUuid = candidates[0].uuid;
15513
+ continue;
15514
+ }
15515
+ throw new Error(
15516
+ `touch '${this.name}' has ${drafts.length} unnamed ${actionType} action(s) and the server has ${candidates.length} \u2014 so there is no way to tell which stored action each one is. Adopting by position swaps their identities the moment an action is inserted or removed, which moves one action's delivery history onto another. Give these actions names (\`{ name: ... }\`) so each one can be matched to the right rule.`
15517
+ );
15518
+ }
15519
+ }
15520
+ /** Attach a `JOURNEY_STEP_EXECUTE` action. Same contract as legacy. */
15521
+ onExecute(actionType, params = {}, options = {}) {
15522
+ this.rules.push({
15523
+ uuid: crypto.randomUUID(),
15524
+ actionType,
15525
+ actionParams: params,
15526
+ options
15527
+ });
15528
+ return this;
15529
+ }
15530
+ sendsSms(params, options = {}) {
15531
+ return this.onExecute("sms:send" /* SMS_SEND */, params, options);
15532
+ }
15533
+ callsMember(params, options = {}) {
15534
+ return this.onExecute("phone:call" /* PHONE_CALL */, params, options);
15535
+ }
15536
+ sendsEmail(params, options = {}) {
15537
+ return this.onExecute("email:send" /* EMAIL_SEND */, params, options);
15538
+ }
15539
+ get hasOutreach() {
15540
+ return this.rules.length > 0;
15541
+ }
15542
+ eventRuleInputs() {
15543
+ return this.rules.map((rule) => ({
15544
+ uuid: rule.adoptedUuid ?? rule.uuid,
15545
+ eventType: "journey_step:execute" /* JOURNEY_STEP_EXECUTE */,
15546
+ actionType: rule.actionType,
15547
+ actionParams: resolveRefs(rule.actionParams),
15548
+ ...rule.options.name ? { name: rule.options.name } : {},
15549
+ ...rule.options.when ? { conditions: rule.options.when } : {},
15550
+ ...rule.options.delaySeconds ? { delay: rule.options.delaySeconds } : {},
15551
+ active: rule.options.active ?? true
15552
+ }));
15553
+ }
15554
+ };
15555
+ var V2EndingBuilder = class extends V2TouchBuilder {
15556
+ constructor(name, when, filterId) {
15557
+ super(name);
15558
+ this.when = when;
15559
+ this.filterId = filterId;
15560
+ }
15561
+ when;
15562
+ filterId;
15563
+ /**
15564
+ * The DECISION RULE uuid, distinct from `_uuid` (the anchor step's).
15565
+ *
15566
+ * An Ending is two rows: a `JourneyDecisionRule` carrying the condition and
15567
+ * precedence, and a `JourneyStep` anchor carrying its actions, goals, and
15568
+ * status history. Adopting only the anchor left the rule to be recreated on
15569
+ * every re-run — and `MemberJourney.latched_ending_rule_id` /
15570
+ * `JourneyStatusLog.journey_decision_rule_id` point at the RULE with
15571
+ * `ON DELETE SET NULL`, so every completed enrollment silently forgot which
15572
+ * Ending it took.
15573
+ */
15574
+ _ruleUuid;
15575
+ /**
15576
+ * An Ending cannot carry a branch, and saying so is the whole override.
15577
+ *
15578
+ * `V2EndingBuilder extends V2TouchBuilder` for the identity and addressing
15579
+ * an Ending's anchor shares with a touch, which also inherits every touch
15580
+ * method — `branch()` among them. Inherited unchanged it would set
15581
+ * `_branch` on an object nothing ever reads it from: the Ending serializer
15582
+ * writes `{uuid|key, name, celCondition, filterId, eventRules}` and no
15583
+ * `branch`, and `allTouches()` walks only the timeline, so the routes are
15584
+ * never numbered, validated, adopted or sent. The author gets no error and
15585
+ * a definition quietly missing what they asked for.
15586
+ *
15587
+ * An Ending is terminal by construction — it is the rule that ENDS an
15588
+ * enrollment — so there is no shape to serialize even if the payload had a
15589
+ * field for it. Refusing at the call is the only point where the author is
15590
+ * still holding the mistake.
15591
+ *
15592
+ * @see foreignAnchorProblem for why this names no Ending.
15593
+ */
15594
+ branch() {
15595
+ throw new Error(
15596
+ "an Ending cannot carry a branch. An Ending terminates an enrollment, so there is nothing after it to route to, and the atomic definition has no field to send one under \u2014 the routes would be silently dropped. Put the branch on the touch that leads to this Ending instead, and give each arm its own Ending."
15597
+ );
15598
+ }
15599
+ };
15600
+ var JourneyV2Builder = class extends WorkspaceBuilderResource {
15601
+ constructor(name, options = {}) {
15602
+ super();
15603
+ this.name = name;
15604
+ this.description = options.description ?? "";
15605
+ this.activate = options.activate ?? false;
15606
+ }
15607
+ name;
15608
+ description;
15609
+ touches = [];
15610
+ endings = [];
15611
+ goals = [];
15612
+ /** Activate after the definition is written and validated. */
15613
+ activate;
15614
+ /** Optimistic-concurrency token, from create or adoption. */
15615
+ _expectedUpdatedAt;
15616
+ /** Server status at adoption — decides whether a re-run must pause first. */
15617
+ _status;
15618
+ /**
15619
+ * A v2 definition write is idempotent, so an ADOPTED journey is written
15620
+ * too. That is the whole point of adopting one: the PUT is a full,
15621
+ * uuid-keyed replacement, so re-running a script is how an author expresses
15622
+ * an edit. The legacy builder stays create-only — its `apply()` only knows
15623
+ * how to create, and re-running it would duplicate.
15624
+ */
15625
+ get appliesWhenExisting() {
15626
+ return true;
15627
+ }
15628
+ /** Append a touch to the timeline. Order is call order. */
15629
+ touch(name, options = {}) {
15630
+ const touch = new V2TouchBuilder(name, options);
15631
+ this.touches.push(touch);
15632
+ return touch;
15633
+ }
15634
+ /**
15635
+ * Every touch in the timeline, arms included, depth first.
15636
+ *
15637
+ * Identity adoption, name-uniqueness and validation all have to see arm
15638
+ * touches — a walk over the top level alone would leave every arm touch
15639
+ * recreated on each re-run, silently archiving its member history.
15640
+ */
15641
+ allTouches() {
15642
+ const out = [];
15643
+ const walk = (touches) => {
15644
+ for (const touch of touches) {
15645
+ out.push(touch);
15646
+ for (const route of touch._branch?.routes ?? []) walk(route.touches);
15647
+ }
15648
+ };
15649
+ walk(this.touches);
15650
+ return out;
15651
+ }
15652
+ /** Every route in the timeline, at every nesting depth, depth first. */
15653
+ allRoutes() {
15654
+ const out = [];
15655
+ for (const touch of this.allTouches()) {
15656
+ for (const route of touch._branch?.routes ?? []) out.push(route);
15657
+ }
15658
+ return out;
15659
+ }
15660
+ /** Append an Ending. Call order is evaluation order. */
15661
+ ending(name, options) {
15662
+ const ending = new V2EndingBuilder(name, options.when, options.filterId);
15663
+ this.endings.push(ending);
15664
+ return ending;
15665
+ }
15666
+ goal(name, options = {}) {
15667
+ this.goals.push({
15668
+ name,
15669
+ description: options.description,
15670
+ step: options.step,
15671
+ completionCel: options.completionCel,
15672
+ value: options.value
15673
+ });
15674
+ return this;
15675
+ }
15676
+ /**
15677
+ * Authoring problems the server's publish validator would reject.
15678
+ *
15679
+ * A different rule set from the legacy builder's on purpose. "No incoming
15680
+ * edge" has no meaning in a timeline — position is the order — and the v2
15681
+ * failure modes are different ones: an action-less touch that is not an
15682
+ * explicit wait, and an Ending with no condition.
15683
+ */
15684
+ validate() {
15685
+ const problems = [];
15686
+ if (!this.touches.length) {
15687
+ problems.push(
15688
+ `journey '${this.name}' has no touches \u2014 an empty timeline has nothing to execute.`
15689
+ );
15690
+ }
15691
+ const armHeads = new Set(
15692
+ this.allRoutes().map((route) => route.touches[0]).filter(Boolean)
15693
+ );
15694
+ this.allTouches().forEach((touch) => {
15695
+ if (touch.hasOutreach) return;
15696
+ const wait = touch.options.wait;
15697
+ const isFirst = this.touches[0] === touch;
15698
+ const isExplicitWait = !isFirst && !armHeads.has(touch) && (wait?.afterDays !== void 0 || !!wait?.when || wait?.filterId !== void 0);
15699
+ if (isExplicitWait) return;
15700
+ problems.push(
15701
+ `touch '${touch.name}' has no JOURNEY_STEP_EXECUTE action \u2014 a member reaching it gets nothing. Add one, or give it a wait so it is an explicit grace period.`
15702
+ );
15703
+ });
15704
+ for (const touch of this.allTouches()) {
15705
+ const branch = touch._branch;
15706
+ if (!branch) continue;
15707
+ const fallbacks = branch.routes.filter(
15708
+ (route) => !route.options.when?.trim() && route.options.filterId === void 0
15709
+ );
15710
+ if (branch.routes.length - fallbacks.length < 1) {
15711
+ problems.push(
15712
+ `branch after touch '${touch.name}' needs at least one conditional route \u2014 one declared with a \`when\`, a \`filterId\`, or both. Members wait at the branch until a route matches, so an Otherwise is optional.`
15713
+ );
15714
+ }
15715
+ if (fallbacks.length > 1) {
15716
+ problems.push(
15717
+ `branch after touch '${touch.name}' declares ${fallbacks.length} Otherwise routes; a branch has at most one unconditional fallback.`
15718
+ );
15719
+ }
15720
+ if (fallbacks.length === 1 && branch.routes[branch.routes.length - 1] !== fallbacks[0]) {
15721
+ problems.push(
15722
+ `the Otherwise route of the branch after touch '${touch.name}' is not last; it is taken immediately, so any route after it can never be reached.`
15723
+ );
15724
+ }
15725
+ for (const route of branch.routes) {
15726
+ if (!route.touches.length && !route.options.continueAt) {
15727
+ problems.push(
15728
+ `route '${route.name}' has no target \u2014 give it at least one touch, or a \`continueAt\` naming the touch it continues to.`
15729
+ );
15730
+ }
15731
+ }
15732
+ }
15733
+ for (const ending of this.endings) {
15734
+ if (!ending.when?.trim() && ending.filterId === void 0) {
15735
+ problems.push(
15736
+ `ending '${ending.name}' has no condition \u2014 an Ending that always matches terminates every enrolment on evaluation order alone. Give it a \`when\` expression, a \`filterId\`, or both.`
15737
+ );
15738
+ }
15739
+ }
15740
+ return problems;
15741
+ }
15742
+ /**
15743
+ * Shapes this definition cannot express, found BEFORE anything is written.
15744
+ *
15745
+ * A different list from {@link validate}, and a different consequence:
15746
+ * those are warnings the orchestrator prints and then writes anyway, these
15747
+ * are refusals. For each one the payload has no way to say what the script
15748
+ * asked for, so serializing past it would write a DIFFERENT program from
15749
+ * the one the script wrote, with nothing afterwards to say so.
15750
+ *
15751
+ * It has to run before the first write rather than during serialization,
15752
+ * because {@link apply} creates the Journey — or pauses a live one — before
15753
+ * it builds the payload. A refusal raised from `definitionPayload()` has
15754
+ * therefore already left an empty journey shell behind, or taken a
15755
+ * production program off the air.
15756
+ *
15757
+ * PURE: reads only what the script declared, never what the server holds,
15758
+ * so it is correct at any point — before adoption included — and
15759
+ * `WorkspaceBuilder.preflight()` can stay a synchronous, side-effect-free
15760
+ * check a caller may run directly. Nothing here needs adoption to have run:
15761
+ * an anchor the server has not seen is addressed by its request-local key,
15762
+ * so "has this Ending been saved" is no longer a question a refusal
15763
+ * depends on.
15764
+ */
15765
+ preflight() {
15766
+ const problems = [];
15767
+ this.allTouches().forEach((touch, index) => {
15768
+ const wait = touch.options.wait;
15769
+ if (wait?.afterDays !== void 0 && wait.when) {
15770
+ problems.push(waitExclusivityProblem(index));
15771
+ }
15772
+ });
15773
+ const owned = this.ownedAnchors();
15774
+ this.goals.forEach((goal, index) => {
15775
+ const step = goal.step;
15776
+ if (step && !owned.has(step)) {
15777
+ problems.push(foreignAnchorProblem(index, anchorKind(step)));
15778
+ }
15779
+ });
15780
+ const stepNames = [
15781
+ ...this.allTouches().map((touch) => touch.name),
15782
+ ...this.endings.map((ending) => ending.name)
15783
+ ];
15784
+ const claims = /* @__PURE__ */ new Map();
15785
+ for (const name of stepNames) claims.set(name, (claims.get(name) ?? 0) + 1);
15786
+ const repeated = [...claims.values()].filter((count) => count > 1).length;
15787
+ if (repeated) problems.push(sharedStepNameProblem(repeated));
15788
+ const nameless = stepNames.filter((name) => !name).length;
15789
+ if (nameless) problems.push(namelessStepProblem(nameless));
15790
+ return problems;
15791
+ }
15792
+ /**
15793
+ * Every step a goal in THIS journey can anchor to, compared by object
15794
+ * identity — touches AND Endings, which is why the element type names both
15795
+ * rather than leaning on `V2EndingBuilder extends V2TouchBuilder` to smuggle
15796
+ * Endings in under a touch-only annotation.
15797
+ *
15798
+ * A goal anchored to some other journey's builder is not a near miss the
15799
+ * server can catch: an unsaved one sends a `stepKey` this definition never
15800
+ * declares (a 404 whose cause is invisible), and a SAVED one sends a real
15801
+ * `stepUuid` belonging to a live step somewhere else.
15802
+ */
15803
+ ownedAnchors() {
15804
+ return /* @__PURE__ */ new Set([...this.allTouches(), ...this.endings]);
15805
+ }
15806
+ planLine() {
15807
+ const parts = [];
15808
+ const touchCount = this.allTouches().length;
15809
+ const routeCount = this.allRoutes().length;
15810
+ if (touchCount) parts.push(`${touchCount} touches`);
15811
+ if (routeCount) parts.push(`${routeCount} routes`);
15812
+ if (this.endings.length) parts.push(`${this.endings.length} endings`);
15813
+ if (this.goals.length) parts.push(`${this.goals.length} goals`);
15814
+ return `Journey (v2): ${this.name}${parts.length ? ` (${parts.join(", ")})` : ""}`;
15815
+ }
15816
+ /**
15817
+ * Re-attach every stable child identity the server already holds.
15818
+ *
15819
+ * The atomic endpoint is a FULL REPLACEMENT keyed on uuids: an omitted
15820
+ * uuid does not mean "unchanged", it means "create a new one and archive
15821
+ * whatever the old one was". So anything this misses is silently recreated
15822
+ * on every re-run of the same script — and a script is normally re-run,
15823
+ * because a program is built in stages. Each identity has a different thing
15824
+ * hanging off it, and losing it costs something specific:
15825
+ *
15826
+ * | identity | what re-creating it destroys |
15827
+ * |---|---|
15828
+ * | touch step uuid | the touch's `MemberJourneyStep` history |
15829
+ * | EventRule uuid | that action's delivery bookkeeping |
15830
+ * | Ending RULE uuid | which Ending completed enrollments latched |
15831
+ * | Ending anchor uuid | the Ending's status history and goal anchor |
15832
+ * | goal uuid | every member's satisfaction row for that goal |
15833
+ *
15834
+ * `existing` is the journey DETAIL or AUTHORING projection. Both carry
15835
+ * `steps[].eventRules`, `goals`, and `decisionRules` —
15836
+ * the read projection redacts CEL, not identity — so one fetch is enough
15837
+ * and no second round trip is needed. (The orchestrator asks for the
15838
+ * authoring projection anyway: this builder holds `journeys:write` because
15839
+ * it is about to PUT, and the superset costs nothing.)
15840
+ *
15841
+ * Names are the only key available on a FIRST adoption, and a duplicate
15842
+ * name makes adoption a coin flip between two live resources. That throws
15843
+ * rather than guessing: silently attaching a touch to the wrong step
15844
+ * archives real member history.
15845
+ */
15846
+ adopt(existing) {
15847
+ super.adopt(existing);
15848
+ this._expectedUpdatedAt = existing.updatedAt;
15849
+ this._status = existing.status;
15850
+ this.assertUnambiguousNames();
15851
+ this.adoptChildIdentities(existing);
15852
+ }
15853
+ /** Reject a script whose own names cannot identify a resource. */
15854
+ assertUnambiguousNames() {
15855
+ assertUniqueNames(
15856
+ this.allTouches().map((touch) => touch.name),
15857
+ `journey '${this.name}'`,
15858
+ "touch"
15859
+ );
15860
+ assertUniqueNames(
15861
+ this.allRoutes().map((route) => route.name),
15862
+ `journey '${this.name}'`,
15863
+ "route"
15864
+ );
15865
+ assertUniqueNames(
15866
+ this.endings.map((ending) => ending.name),
15867
+ `journey '${this.name}'`,
15868
+ "ending"
15869
+ );
15870
+ assertUniqueNames(
15871
+ this.goals.map((goal) => goal.name),
15872
+ `journey '${this.name}'`,
15873
+ "goal"
15874
+ );
15875
+ for (const touch of [...this.allTouches(), ...this.endings]) {
15876
+ const names = touch.rules.map((rule) => rule.options.name).filter(Boolean);
15877
+ assertUniqueNames(names, `touch '${touch.name}'`, "action name");
15878
+ }
15879
+ }
15880
+ adoptChildIdentities(payload) {
15881
+ const steps = payload.steps ?? [];
15882
+ const referencedStepNames = /* @__PURE__ */ new Set([
15883
+ ...this.allTouches().map((touch) => touch.name),
15884
+ ...this.endings.map((ending) => ending.name)
15885
+ ]);
15886
+ const stepsByName = indexStoredByName(
15887
+ steps,
15888
+ referencedStepNames,
15889
+ `journey '${this.name}'`,
15890
+ "step"
15891
+ );
15892
+ const stepsById = new Map(steps.map((step) => [step.id, step]));
15893
+ for (const touch of this.allTouches()) {
15894
+ const match = stepsByName.get(touch.name);
15895
+ if (!match) continue;
15896
+ touch._uuid = match.uuid;
15897
+ touch.adoptRuleUuids(match.eventRules ?? []);
15898
+ }
15899
+ const routeRules = (payload.decisionRules ?? []).filter(
15900
+ (rule) => rule.sourceStepId !== null && rule.sourceStepId !== void 0
15901
+ );
15902
+ const declaredRoutes = this.allRoutes();
15903
+ const routesByName = indexStoredByName(
15904
+ routeRules,
15905
+ new Set(declaredRoutes.map((route) => route.name)),
15906
+ `journey '${this.name}'`,
15907
+ "route"
15908
+ );
15909
+ for (const route of declaredRoutes) {
15910
+ const stored = routesByName.get(route.name);
15911
+ if (stored) route._ruleUuid = stored.uuid;
15912
+ }
15913
+ const endingRules = (payload.decisionRules ?? []).filter(
15914
+ (rule) => rule.sourceStepId === null || rule.sourceStepId === void 0
15915
+ );
15916
+ const rulesByName = indexStoredByName(
15917
+ endingRules,
15918
+ new Set(this.endings.map((ending) => ending.name)),
15919
+ `journey '${this.name}'`,
15920
+ "ending"
15921
+ );
15922
+ for (const ending of this.endings) {
15923
+ const rule = rulesByName.get(ending.name);
15924
+ const anchor = rule ? stepsById.get(rule.targetStepId) : stepsByName.get(ending.name);
15925
+ if (rule) ending._ruleUuid = rule.uuid;
15926
+ if (!anchor) continue;
15927
+ ending._uuid = anchor.uuid;
15928
+ ending.adoptRuleUuids(anchor.eventRules ?? []);
15929
+ }
15930
+ const goalsByName = indexStoredByName(
15931
+ payload.goals ?? [],
15932
+ new Set(this.goals.map((goal) => goal.name)),
15933
+ `journey '${this.name}'`,
15934
+ "goal"
15935
+ );
15936
+ for (const goal of this.goals) {
15937
+ const match = goalsByName.get(goal.name);
15938
+ if (match) goal._uuid = match.uuid;
15939
+ }
15940
+ }
15941
+ /** The atomic request body. Exposed so a test can assert it without HTTP. */
15942
+ definitionPayload() {
15943
+ const owned = this.ownedAnchors();
15944
+ const positions = new Map(
15945
+ this.allTouches().map((touch, index) => [touch, index])
15946
+ );
15947
+ return {
15948
+ expectedUpdatedAt: this._expectedUpdatedAt ?? "",
15949
+ touches: this.touches.map((touch) => serializeV2Touch(touch, positions)),
15950
+ endings: this.endings.map((ending) => ({
15951
+ ...ending._ruleUuid ? { uuid: ending._ruleUuid } : {},
15952
+ // Anchor address, exactly as `serializeV2Touch` sends a touch's:
15953
+ // the saved anchor's uuid, or the request-local `key` a goal in
15954
+ // this same save names it by. Both come from `_address`, so the
15955
+ // Ending and the goal cannot be sent under two spellings.
15956
+ ...ending._uuid ? { anchorUuid: ending._uuid } : { key: ending._address },
15957
+ name: ending.name,
15958
+ // The two predicates are sent INDEPENDENTLY (rule-filters plan
15959
+ // §3.2). A filter-only Ending carries no `celCondition` at all
15960
+ // rather than an empty one the server would have to normalize.
15961
+ ...ending.when ? { celCondition: ending.when } : {},
15962
+ ...ending.filterId !== void 0 ? { filterId: ending.filterId } : {},
15963
+ eventRules: ending.eventRuleInputs()
15964
+ })),
15965
+ // ALWAYS sent, `[]` included. The field distinguishes omitted (leave
15966
+ // goals alone) from empty (delete them), and this builder owns the
15967
+ // goal list — so omitting an empty list would make goal REMOVAL the
15968
+ // one edit a script cannot express: delete the `.goal(...)` call, re-run,
15969
+ // and the goal stays live forever.
15970
+ goals: this.goals.map((goal, index) => ({
15971
+ ...goal._uuid ? { uuid: goal._uuid } : {},
15972
+ name: goal.name,
15973
+ ...goal.description ? { description: goal.description } : {},
15974
+ ...serializeV2GoalAnchor(goal.step, index, owned),
15975
+ ...goal.completionCel ? { completionCel: goal.completionCel } : {},
15976
+ ...goal.value !== void 0 ? { value: goal.value } : {}
15977
+ }))
15978
+ };
15979
+ }
15980
+ async apply(client) {
15981
+ const problems = this.preflight();
15982
+ if (problems.length) {
15983
+ throw new Error(
15984
+ `Journey (v2) has ${problems.length} problem(s) and was not applied:
15985
+ ` + problems.map((problem) => ` - ${problem}`).join("\n")
15986
+ );
15987
+ }
15988
+ if (!this._existed) {
15989
+ const created = await client.createJourney({
15990
+ name: this.name,
15991
+ description: this.description,
15992
+ // Explicit, always. An omitted executionModel means `legacy` on the
15993
+ // server, so a v2 builder that forgot it would quietly author a
15994
+ // legacy Journey that happens to look like a timeline.
15995
+ executionModel: "v2"
15996
+ });
15997
+ this._id = created.id;
15998
+ this._uuid = created.uuid;
15999
+ this._created = true;
16000
+ this._expectedUpdatedAt = created.updatedAt;
16001
+ } else if (this._status === "active" && this.activate) {
16002
+ const paused = await client.updateJourney(this.id, { status: "paused" });
16003
+ this._expectedUpdatedAt = paused.updatedAt;
16004
+ }
16005
+ const saved = await client.putJourneyV2Definition(this.id, this.definitionPayload());
16006
+ this._expectedUpdatedAt = saved.updatedAt;
16007
+ this.adoptWrittenUuids(saved);
16008
+ if (this.activate) {
16009
+ await client.updateJourney(this.id, { status: "active" });
16010
+ }
16011
+ }
16012
+ /**
16013
+ * Re-attach the uuids the server assigned, so a follow-up write matches.
16014
+ *
16015
+ * The PUT returns the AUTHORING projection, which is the same shape
16016
+ * `adopt` reads — so this is the same operation against a payload we just
16017
+ * caused, and it uses the same code path rather than a second, thinner
16018
+ * copy that would drift.
16019
+ */
16020
+ adoptWrittenUuids(saved) {
16021
+ this.adoptChildIdentities(saved);
16022
+ }
16023
+ };
16024
+ function indexStoredByName(rows, referenced, owner, kind) {
16025
+ const byName = /* @__PURE__ */ new Map();
16026
+ const counts = /* @__PURE__ */ new Map();
16027
+ for (const row of rows) {
16028
+ const name = row.name;
16029
+ if (typeof name !== "string" || !name) continue;
16030
+ counts.set(name, (counts.get(name) ?? 0) + 1);
16031
+ if (!byName.has(name)) byName.set(name, row);
16032
+ }
16033
+ for (const [name, count] of counts) {
16034
+ if (count < 2 || !referenced.has(name)) continue;
16035
+ throw new Error(
16036
+ `${owner} already has ${count} ${kind}s named '${name}'. This script adopts by name, so it cannot tell which ${kind} it owns \u2014 and the one it does not pick is archived on the next save, taking its history with it. Rename them so each name identifies one ${kind}.`
16037
+ );
16038
+ }
16039
+ return byName;
16040
+ }
16041
+ function assertUniqueNames(names, owner, kind) {
16042
+ const seen = /* @__PURE__ */ new Set();
16043
+ for (const name of names) {
16044
+ if (seen.has(name)) {
16045
+ throw new Error(
16046
+ `${owner} has two ${kind}s named '${name}'. The v2 builder adopts an existing journey by name, so duplicates would attach a builder to either one at random \u2014 archiving the other's history on the next save. Rename one.`
16047
+ );
16048
+ }
16049
+ seen.add(name);
16050
+ }
16051
+ }
16052
+ function serializeV2Touch(touch, positions) {
16053
+ return {
16054
+ ...touch._uuid ? { uuid: touch._uuid } : { key: touch._address },
16055
+ name: touch.name,
16056
+ ...touch.options.description ? { description: touch.options.description } : {},
16057
+ ...touch.options.wait ? { wait: buildV2Wait(touch.options.wait, positions.get(touch)) } : {},
16058
+ eventRules: touch.eventRuleInputs(),
16059
+ ...touch._branch ? {
16060
+ branch: {
16061
+ routes: touch._branch.routes.map((route) => ({
16062
+ ...route._ruleUuid ? { uuid: route._ruleUuid } : {},
16063
+ name: route.name,
16064
+ // Omitted, not null, and INDEPENDENT of each other: a route
16065
+ // with neither predicate IS the Otherwise marker, one with
16066
+ // either is conditional, and one with both is ANDed
16067
+ // (rule-filters plan §3.2). The server normalizes "" to the
16068
+ // same thing as omitted.
16069
+ ...route.options.when ? { celCondition: route.options.when } : {},
16070
+ ...route.options.filterId !== void 0 ? { filterId: route.options.filterId } : {},
16071
+ touches: route.touches.map((armTouch) => serializeV2Touch(armTouch, positions)),
16072
+ ...route.options.continueAt ? { continueAt: route.options.continueAt._address } : {}
16073
+ }))
16074
+ }
16075
+ } : {}
16076
+ };
16077
+ }
16078
+ function serializeV2GoalAnchor(step, goalIndex, owned) {
16079
+ if (!step) return {};
16080
+ if (!owned.has(step)) throw new Error(foreignAnchorProblem(goalIndex, anchorKind(step)));
16081
+ if (step._uuid) return { stepUuid: step._uuid };
16082
+ return { stepKey: step._address };
16083
+ }
16084
+ function foreignAnchorProblem(goalIndex, kind) {
16085
+ return `goal at index ${goalIndex} is anchored to ${kind === "Ending" ? "an" : "a"} ${kind} that belongs to a different journey builder. A goal anchor is part of the same atomic definition as its step, so it can only name a touch or Ending this journey declares.`;
16086
+ }
16087
+ function waitExclusivityProblem(touchIndex) {
16088
+ const where = touchIndex === void 0 ? "this touch" : `touch at index ${touchIndex}`;
16089
+ return `${where} sets both afterDays and when; fold the day count into \`when\`. A v2 wait is either a whole-day count or Advanced CEL, not both.`;
16090
+ }
16091
+ function sharedStepNameProblem(count) {
16092
+ return `${count} step name(s) are claimed more than once. Touches and Endings are one namespace: until a save mints their uuids they address themselves by name and the definition resolves those keys through one field, and once saved they are stored steps the next run cannot tell apart. Names are canonical (trimmed), as the API stores them. Rename one.`;
16093
+ }
16094
+ function namelessStepProblem(count) {
16095
+ return `${count} step(s) have an empty name once trimmed. A step's name is its request-local address until a save mints its uuid, so a nameless one has nothing to be addressed by, and the API refuses it. Name them.`;
16096
+ }
16097
+ function anchorKind(step) {
16098
+ return step instanceof V2EndingBuilder ? "Ending" : "touch";
16099
+ }
16100
+ function buildV2Wait(wait, touchIndex) {
16101
+ if (wait.afterDays !== void 0 && wait.when) {
16102
+ throw new Error(waitExclusivityProblem(touchIndex));
16103
+ }
16104
+ const extras = {
16105
+ ...wait.filterId !== void 0 ? { filterId: wait.filterId } : {}
16106
+ };
16107
+ if (wait.afterDays !== void 0) {
16108
+ return { kind: "wholeDays", days: wait.afterDays, ...extras };
16109
+ }
16110
+ if (wait.when) {
16111
+ return { kind: "advanced", cel: wait.when, ...extras };
16112
+ }
16113
+ return { kind: "none", ...extras };
16114
+ }
14340
16115
 
14341
16116
  // src/workspace-builder/role-update.ts
14342
16117
  var RoleUpdate = class extends WorkspaceBuilderResource {
@@ -14572,6 +16347,7 @@ var AgentBuilder = class extends WorkspaceBuilderResource {
14572
16347
  this.memberRoleId = options.roleId ?? options.role_id;
14573
16348
  this.tools = options.tools ?? [];
14574
16349
  this.codeInterpreterEnabled = options.codeInterpreterEnabled ?? options.code_interpreter_enabled ?? false;
16350
+ this.webBrowserEnabled = options.webBrowserEnabled ?? options.web_browser_enabled ?? false;
14575
16351
  }
14576
16352
  name;
14577
16353
  chatModelId;
@@ -14579,6 +16355,7 @@ var AgentBuilder = class extends WorkspaceBuilderResource {
14579
16355
  memberRoleId;
14580
16356
  tools;
14581
16357
  codeInterpreterEnabled;
16358
+ webBrowserEnabled;
14582
16359
  planLine() {
14583
16360
  const parts = [];
14584
16361
  if (this.chatModelId) parts.push(`model=${this.chatModelId}`);
@@ -14599,7 +16376,8 @@ var AgentBuilder = class extends WorkspaceBuilderResource {
14599
16376
  chatModelId: this.chatModelId,
14600
16377
  systemPrompt: this.systemPrompt,
14601
16378
  ...this.tools.length ? { tools: this.tools } : {},
14602
- ...this.codeInterpreterEnabled ? { codeInterpreterEnabled: true } : {}
16379
+ ...this.codeInterpreterEnabled ? { codeInterpreterEnabled: true } : {},
16380
+ ...this.webBrowserEnabled ? { webBrowserEnabled: true } : {}
14603
16381
  };
14604
16382
  const result = await client.createAgent(payload);
14605
16383
  this._id = result.id;
@@ -14620,6 +16398,9 @@ var PHASES = /* @__PURE__ */ new Map([
14620
16398
  [RoutineBuilder, 6],
14621
16399
  [NotificationRuleBuilder, 6],
14622
16400
  [JourneyBuilder, 7],
16401
+ // Same phase as the legacy builder: a v2 Journey is written whole by its
16402
+ // own apply(), so it has no child resources to sequence after it.
16403
+ [JourneyV2Builder, 7],
14623
16404
  [JourneyStepBuilder, 8]
14624
16405
  ]);
14625
16406
  var LIST_PAGE_SIZE = 100;
@@ -14681,6 +16462,21 @@ var WorkspaceBuilder = class {
14681
16462
  this.resources.push(journey);
14682
16463
  return journey;
14683
16464
  }
16465
+ /**
16466
+ * A Journey v2 timeline (plan §3.8): ordered touches, structured waits, and
16467
+ * ordered Endings, written through the atomic definition endpoint.
16468
+ *
16469
+ * A separate factory rather than an option on {@link journey}, because the
16470
+ * two return different builders with different vocabularies — `.touch()`
16471
+ * and `.ending()` versus `.step()` and `.connectsTo()`. The legacy builder
16472
+ * keeps its current behaviour untouched, which is the plan's explicit
16473
+ * compatibility requirement.
16474
+ */
16475
+ journeyV2(name, options = {}) {
16476
+ const journey = new JourneyV2Builder(name, options);
16477
+ this.resources.push(journey);
16478
+ return journey;
16479
+ }
14684
16480
  agent(name, options = {}) {
14685
16481
  const agent = new AgentBuilder(name, options);
14686
16482
  this.resources.push(agent);
@@ -14764,7 +16560,9 @@ ${"=".repeat(50)}`);
14764
16560
  * surfaced before the write rather than discovered from a member's phone.
14765
16561
  */
14766
16562
  reportJourneyWarnings() {
14767
- const problems = this.resources.filter((resource) => resource instanceof JourneyBuilder).flatMap((journey) => journey.validate());
16563
+ const problems = this.resources.filter(
16564
+ (resource) => resource instanceof JourneyBuilder || resource instanceof JourneyV2Builder
16565
+ ).flatMap((journey) => journey.validate());
14768
16566
  if (!problems.length) return;
14769
16567
  writeLine("\n Journey warnings:");
14770
16568
  for (const problem of problems) writeLine(` ! ${problem}`);
@@ -14781,6 +16579,12 @@ ${"=".repeat(50)}`);
14781
16579
  * Deliberately narrow: only cross-resource facts the builder can see with
14782
16580
  * certainty. Per-field CEL schema checking stays server-side, where the
14783
16581
  * real validator lives — duplicating it here would drift.
16582
+ *
16583
+ * Pure: reads only what the plan declares, never what the server holds, so
16584
+ * it is correct before adoption and safe for a caller to run directly. It
16585
+ * is also the WHOLE gate: every anchor a v2 definition can name has a
16586
+ * request-local address whether or not the server has seen it, so no
16587
+ * refusal has to wait for adoption to decide it.
14784
16588
  */
14785
16589
  preflight() {
14786
16590
  const problems = [];
@@ -14804,39 +16608,46 @@ ${"=".repeat(50)}`);
14804
16608
  }
14805
16609
  }
14806
16610
  }
16611
+ for (const resource of this.resources) {
16612
+ if (resource instanceof JourneyV2Builder) problems.push(...resource.preflight());
16613
+ }
14807
16614
  return [...new Set(problems)];
14808
16615
  }
14809
- async apply() {
14810
- const problems = this.preflight();
14811
- if (problems.length) {
14812
- writeLine("\nPlan rejected \u2014 nothing was created:");
14813
- for (const problem of problems) writeLine(` ! ${problem}`);
14814
- throw new Error(
14815
- `Plan has ${problems.length} problem(s) and was not applied:
16616
+ /** The plan-rejection shape: every problem printed, nothing written. */
16617
+ rejectIfProblems(problems) {
16618
+ if (!problems.length) return;
16619
+ writeLine("\nPlan rejected \u2014 nothing was created:");
16620
+ for (const problem of problems) writeLine(` ! ${problem}`);
16621
+ throw new Error(
16622
+ `Plan has ${problems.length} problem(s) and was not applied:
14816
16623
  ` + problems.map((problem) => ` - ${problem}`).join("\n")
14817
- );
14818
- }
16624
+ );
16625
+ }
16626
+ async apply() {
14819
16627
  const resources = this.sortedResources();
16628
+ this.rejectIfProblems(this.preflight());
14820
16629
  await this.resolveExisting(resources);
14821
16630
  const summary = {};
14822
16631
  writeLine("Applying...");
14823
16632
  for (const resource of resources) {
14824
16633
  try {
14825
16634
  if (resource.isImplicit) continue;
14826
- if (resource._existed) {
16635
+ if (resource._existed && !resource.appliesWhenExisting) {
14827
16636
  const key = resourceKey(resource);
14828
16637
  summary[key] ??= [];
14829
16638
  summary[key].push(resource._id);
14830
16639
  writeLine(` Exists ${resource.planLine()} -> id=${resource._id}`);
14831
16640
  continue;
14832
16641
  }
16642
+ const updating = resource._existed;
14833
16643
  await resource.apply(this.client);
14834
16644
  if (resource._created || resource._id !== void 0) {
14835
16645
  const key = resourceKey(resource);
14836
16646
  summary[key] ??= [];
14837
16647
  summary[key].push(resource._id);
14838
16648
  const startTag = resource instanceof TaskBuilder && resource.start ? " [start]" : "";
14839
- writeLine(` Created ${resource.planLine()}${startTag} -> id=${resource._id}`);
16649
+ const verb = updating ? "Updated" : "Created";
16650
+ writeLine(` ${verb} ${resource.planLine()}${startTag} -> id=${resource._id}`);
14840
16651
  } else {
14841
16652
  writeLine(` Skipped: ${resource.planLine()}`);
14842
16653
  }
@@ -14855,6 +16666,11 @@ Done! Created ${count} resources.`);
14855
16666
  return summary;
14856
16667
  }
14857
16668
  async resolveExisting(resources) {
16669
+ assertUniqueJourneyNames(
16670
+ resources.filter(
16671
+ (resource) => resource instanceof JourneyBuilder || resource instanceof JourneyV2Builder
16672
+ )
16673
+ );
14858
16674
  const formSlugs = new Map(
14859
16675
  resources.filter((resource) => resource instanceof FormBuilder).map((resource) => [resource.slug, resource])
14860
16676
  );
@@ -14893,14 +16709,33 @@ Done! Created ${count} resources.`);
14893
16709
  }
14894
16710
  }
14895
16711
  const journeyNames = new Map(
14896
- resources.filter((resource) => resource instanceof JourneyBuilder).map((resource) => [resource.name, resource])
16712
+ resources.filter(
16713
+ (resource) => resource instanceof JourneyBuilder || resource instanceof JourneyV2Builder
16714
+ ).map((resource) => [resource.name, resource])
14897
16715
  );
14898
16716
  if (journeyNames.size) {
14899
- const existingJourneys = await this.client.getJourneys();
14900
- for (const existing of existingJourneys.items) {
16717
+ const pageSize = 500;
16718
+ const firstPage = await this.client.getJourneys(false, { page: 1, pageSize });
16719
+ const allJourneys = [...firstPage.items];
16720
+ for (let page = 2; page <= firstPage.totalPages; page++) {
16721
+ const nextPage = await this.client.getJourneys(false, { page, pageSize });
16722
+ allJourneys.push(...nextPage.items);
16723
+ }
16724
+ const storedByName = /* @__PURE__ */ new Map();
16725
+ for (const existing of allJourneys) {
14901
16726
  if (!existing.name || !journeyNames.has(existing.name)) continue;
14902
- const detail = await this.client.getJourney(existing.id);
14903
- journeyNames.get(existing.name).adopt(detail);
16727
+ storedByName.set(existing.name, [...storedByName.get(existing.name) ?? [], existing]);
16728
+ }
16729
+ for (const [name, matches] of storedByName) {
16730
+ if (matches.length > 1) {
16731
+ throw new Error(
16732
+ `This workspace has ${matches.length} journeys named '${name}', and the script adopts an existing journey by name \u2014 so it cannot tell which one it owns. Adopting the wrong one replaces that journey whole on the next save. Rename the others in the app, or rename the journey in the script.`
16733
+ );
16734
+ }
16735
+ const existing = matches[0];
16736
+ const builder = journeyNames.get(name);
16737
+ const detail = builder instanceof JourneyV2Builder ? await this.client.getJourneyAuthoring(existing.id) : await this.client.getJourney(existing.id);
16738
+ builder.adopt(detail);
14904
16739
  }
14905
16740
  }
14906
16741
  const agentNames = new Map(
@@ -15079,6 +16914,12 @@ Done! Created ${count} resources.`);
15079
16914
  }
15080
16915
  } else if (resource instanceof JourneyBuilder) {
15081
16916
  for (const goal of resource.goals) lines.push(`Goal: ${goal.name}`);
16917
+ } else if (resource instanceof JourneyV2Builder) {
16918
+ resource.touches.forEach((touch, index) => {
16919
+ lines.push(`${index + 1}. ${touch.name}`);
16920
+ });
16921
+ for (const ending of resource.endings) lines.push(`Ending: ${ending.name}`);
16922
+ for (const goal of resource.goals) lines.push(`Goal: ${goal.name}`);
15082
16923
  }
15083
16924
  }
15084
16925
  return lines;
@@ -15237,6 +17078,17 @@ var ApplyError = class extends Error {
15237
17078
  return this.#cause;
15238
17079
  }
15239
17080
  };
17081
+ function assertUniqueJourneyNames(journeys) {
17082
+ const seen = /* @__PURE__ */ new Set();
17083
+ for (const journey of journeys) {
17084
+ if (seen.has(journey.name)) {
17085
+ throw new Error(
17086
+ `This script declares two journeys named '${journey.name}'. A journey is adopted and re-applied by name, so only one of them could ever be written \u2014 and a v2 apply replaces the journey it adopted whole. Rename one.`
17087
+ );
17088
+ }
17089
+ seen.add(journey.name);
17090
+ }
17091
+ }
15240
17092
  function resourceKey(resource) {
15241
17093
  if (resource instanceof RoleUpdate) return "roleUpdates";
15242
17094
  if (resource instanceof FormBuilder) return "forms";
@@ -15246,7 +17098,9 @@ function resourceKey(resource) {
15246
17098
  if (resource instanceof MemberFilterBuilder) return "memberFilters";
15247
17099
  if (resource instanceof RoutineBuilder) return "routines";
15248
17100
  if (resource instanceof NotificationRuleBuilder) return "notificationRules";
15249
- if (resource instanceof JourneyBuilder) return "journeys";
17101
+ if (resource instanceof JourneyBuilder || resource instanceof JourneyV2Builder) {
17102
+ return "journeys";
17103
+ }
15250
17104
  if (resource instanceof JourneyStepBuilder) return "journeySteps";
15251
17105
  if (resource instanceof AgentBuilder) return "agents";
15252
17106
  return "resources";
@@ -15357,7 +17211,7 @@ function writeScopeForResource(resource) {
15357
17211
  if (resource instanceof RoutineBuilder || resource instanceof NotificationRuleBuilder) {
15358
17212
  return "automations:admin";
15359
17213
  }
15360
- if (resource instanceof JourneyBuilder || resource instanceof JourneyStepBuilder) {
17214
+ if (resource instanceof JourneyBuilder || resource instanceof JourneyStepBuilder || resource instanceof JourneyV2Builder) {
15361
17215
  return "journeys:write";
15362
17216
  }
15363
17217
  if (resource instanceof RoleUpdate) return "member_roles:write";
@@ -15501,6 +17355,30 @@ var QUERY_VALUELESS_OPS = /* @__PURE__ */ new Set([
15501
17355
  "exists"
15502
17356
  ]);
15503
17357
 
17358
+ // src/types/generated/channel_message.ts
17359
+ var ChannelMessageDirection = {
17360
+ inbound: "inbound",
17361
+ outbound: "outbound"
17362
+ };
17363
+ var ChannelMessageSource = {
17364
+ sms_record: "sms_record",
17365
+ other_chat: "other_chat"
17366
+ };
17367
+
17368
+ // src/types/generated/chat.ts
17369
+ var ChannelMessagesUnavailableReason = {
17370
+ not_single_channel: "not_single_channel",
17371
+ no_phone_number: "no_phone_number",
17372
+ no_counterpart_phone: "no_counterpart_phone"
17373
+ };
17374
+
17375
+ // src/types/generated/ehr_writeback.ts
17376
+ var EhrWritebackOutcomeResponseStatus = {
17377
+ accepted: "accepted",
17378
+ skipped: "skipped",
17379
+ failed: "failed"
17380
+ };
17381
+
15504
17382
  // src/types/chat-types.ts
15505
17383
  var SMS_DELIVERY_FAILURE_STATUSES = /* @__PURE__ */ new Set([
15506
17384
  "failed",
@@ -15657,6 +17535,35 @@ var PromoCodeStatus = {
15657
17535
  exhausted: "exhausted"
15658
17536
  };
15659
17537
 
17538
+ // src/types/generated/import_skipped_rule.ts
17539
+ var ImportSkippedRuleResourceGroupResourceType = {
17540
+ phone: "phone",
17541
+ inbox: "inbox",
17542
+ member: "member"
17543
+ };
17544
+ var ImportSkippedRuleResponseNeededResourceTypesItem = {
17545
+ phone: "phone",
17546
+ inbox: "inbox",
17547
+ member: "member"
17548
+ };
17549
+ var ImportSkippedRuleResponseParentKind = {
17550
+ routine: "routine",
17551
+ journey_step: "journey_step",
17552
+ task: "task",
17553
+ workflow: "workflow",
17554
+ other: "other"
17555
+ };
17556
+ var ImportSkippedRuleResponseReasonCode = {
17557
+ missing_binding: "missing_binding",
17558
+ invalid_event_rule_cel: "invalid_event_rule_cel",
17559
+ unresolved_journey_scope: "unresolved_journey_scope"
17560
+ };
17561
+ var ImportSkippedRuleResponseStatus = {
17562
+ outstanding: "outstanding",
17563
+ reconnected: "reconnected",
17564
+ dismissed: "dismissed"
17565
+ };
17566
+
15660
17567
  // src/features/registry.ts
15661
17568
  var FeatureCategory = /* @__PURE__ */ ((FeatureCategory2) => {
15662
17569
  FeatureCategory2["COMMUNICATION"] = "communication";
@@ -15782,6 +17689,12 @@ function isChatType(value) {
15782
17689
 
15783
17690
  // src/constants/models.ts
15784
17691
  var DEFAULT_CHAT_MODEL = "aws:bedrock:claude-4-5-haiku";
17692
+ var DEFAULT_AGENT_CHAT_MODEL = "openai:chat:gpt-5.6-luna";
17693
+ var DEFAULT_AGENT_REALTIME_MODEL = "xai:realtime:voice-agent-2";
17694
+ var DEFAULT_AGENT_REALTIME_MODEL_CONFIG = {
17695
+ ttsModel: "native",
17696
+ voiceModel: "xai:voice:cosmo"
17697
+ };
15785
17698
  var DEFAULT_VOICE_INFERENCE_MODEL = "openai:chat:gpt-5.6-luna";
15786
17699
  var DEFAULT_CUSTOM_VOICE_MODEL = "elevenlabs:voice:river";
15787
17700
 
@@ -15873,6 +17786,156 @@ function getAllResourceSlugs() {
15873
17786
  return Object.keys(RESOURCE_METADATA);
15874
17787
  }
15875
17788
 
17789
+ // src/types/generated/activity_feed.ts
17790
+ var ActivityGrain = {
17791
+ month: "month",
17792
+ week: "week",
17793
+ day: "day",
17794
+ hour: "hour",
17795
+ event: "event"
17796
+ };
17797
+ var ActivityGroupBy = {
17798
+ workspace: "workspace",
17799
+ event_type: "event_type",
17800
+ family: "family",
17801
+ workspace_family: "workspace_family"
17802
+ };
17803
+ var ActivityOpenItemOrder = {
17804
+ priority: "priority",
17805
+ recency: "recency"
17806
+ };
17807
+ var ActivityWindowBasis = {
17808
+ absolute: "absolute",
17809
+ workspace_local: "workspace_local"
17810
+ };
17811
+
17812
+ // src/types/generated/family.ts
17813
+ var ActivityEventFamily = {
17814
+ people: "people",
17815
+ conversations: "conversations",
17816
+ journeys: "journeys",
17817
+ automation: "automation",
17818
+ operators: "operators",
17819
+ administration: "administration"
17820
+ };
17821
+ var ActivityOutcome = {
17822
+ ok: "ok",
17823
+ attention: "attention",
17824
+ failed: "failed"
17825
+ };
17826
+
17827
+ // src/types/generated/entity_ref.ts
17828
+ var RefResolutionStatus = {
17829
+ resolved: "resolved",
17830
+ unresolved: "unresolved",
17831
+ unsupported: "unsupported"
17832
+ };
17833
+
17834
+ // src/types/generated/event_type.ts
17835
+ var ActivityCapability = {
17836
+ "assignments:read": "assignments:read",
17837
+ "chats:read": "chats:read",
17838
+ "journeys:read": "journeys:read",
17839
+ "members:read": "members:read",
17840
+ "operator:read": "operator:read",
17841
+ "org:read": "org:read",
17842
+ "phones:read": "phones:read",
17843
+ "workflows:read": "workflows:read",
17844
+ "workspace:read": "workspace:read"
17845
+ };
17846
+ var ActivityEventType = {
17847
+ membercreated: "member.created",
17848
+ memberremoved: "member.removed",
17849
+ memberrole_changed: "member.role_changed",
17850
+ memberlabels_changed: "member.labels_changed",
17851
+ memberattributes_changed: "member.attributes_changed",
17852
+ importstarted: "import.started",
17853
+ importcompleted: "import.completed",
17854
+ assignmentstarted: "assignment.started",
17855
+ assignmentconcluded: "assignment.concluded",
17856
+ journeyenrolled: "journey.enrolled",
17857
+ journeyunenrolled: "journey.unenrolled",
17858
+ journeycompleted: "journey.completed",
17859
+ journeystep_transitioned: "journey.step_transitioned",
17860
+ journeyactivated: "journey.activated",
17861
+ chatstarted: "chat.started",
17862
+ chatawaiting_human: "chat.awaiting_human",
17863
+ chathuman_replied: "chat.human_replied",
17864
+ escalationopened: "escalation.opened",
17865
+ escalationresolved: "escalation.resolved",
17866
+ callstarted: "call.started",
17867
+ callcompleted: "call.completed",
17868
+ callmissed: "call.missed",
17869
+ presencewent_online: "presence.went_online",
17870
+ presencewent_offline: "presence.went_offline",
17871
+ operator_groupmember_added: "operator_group.member_added",
17872
+ operator_groupmember_removed: "operator_group.member_removed",
17873
+ voicemailreceived: "voicemail.received",
17874
+ voicemaillistened: "voicemail.listened",
17875
+ routinestarted: "routine.started",
17876
+ routinecompleted: "routine.completed",
17877
+ routinefailed: "routine.failed",
17878
+ workflowpublished: "workflow.published",
17879
+ subscriptionstarted: "subscription.started",
17880
+ subscriptionupdated: "subscription.updated",
17881
+ subscriptioncanceled: "subscription.canceled",
17882
+ member_subscriptionstarted: "member_subscription.started",
17883
+ member_subscriptioncanceled: "member_subscription.canceled",
17884
+ purchasecompleted: "purchase.completed",
17885
+ phone_numberprovisioned: "phone_number.provisioned",
17886
+ phone_numberarchived: "phone_number.archived",
17887
+ domainlinked: "domain.linked",
17888
+ domainverified: "domain.verified",
17889
+ configupdated: "config.updated"
17890
+ };
17891
+ var ActivityVisibility = {
17892
+ workspace: "workspace",
17893
+ org: "org",
17894
+ account_private: "account_private"
17895
+ };
17896
+
17897
+ // src/types/generated/ref.ts
17898
+ var ActorKind = {
17899
+ account: "account",
17900
+ agent: "agent",
17901
+ connection: "connection",
17902
+ member: "member",
17903
+ org_account: "org_account",
17904
+ system: "system"
17905
+ };
17906
+ var EntityKind = {
17907
+ account: "account",
17908
+ org: "org",
17909
+ org_account: "org_account",
17910
+ workspace: "workspace",
17911
+ agent: "agent",
17912
+ connection: "connection",
17913
+ member: "member",
17914
+ assignment: "assignment",
17915
+ journey: "journey",
17916
+ journey_step: "journey_step",
17917
+ routine: "routine",
17918
+ task: "task",
17919
+ workflow: "workflow",
17920
+ workflow_revision: "workflow_revision",
17921
+ call: "call",
17922
+ chat: "chat",
17923
+ escalation: "escalation",
17924
+ inbox: "inbox",
17925
+ phone_number: "phone_number",
17926
+ voicemail: "voicemail",
17927
+ domain: "domain",
17928
+ import: "import",
17929
+ invoice: "invoice",
17930
+ member_label: "member_label",
17931
+ member_subscription: "member_subscription",
17932
+ operator_group: "operator_group",
17933
+ purchase: "purchase",
17934
+ subscription: "subscription",
17935
+ data_type: "data_type",
17936
+ workspace_config: "workspace_config"
17937
+ };
17938
+
15876
17939
  // src/scopes.ts
15877
17940
  var ScopeCategory = /* @__PURE__ */ ((ScopeCategory2) => {
15878
17941
  ScopeCategory2["WORKSPACE"] = "workspace";
@@ -15978,7 +18041,9 @@ var SCOPES = {
15978
18041
  "chats:write": {
15979
18042
  name: "chats:write",
15980
18043
  category: "chats" /* CHATS */,
15981
- description: "Send messages in conversations",
18044
+ // Cross-member: acting in a conversation that is not yours. Sending in
18045
+ // your own needs no scope (see the chats:read note on "all").
18046
+ description: "Modify other members' conversations",
15982
18047
  implies: ["chats:read"]
15983
18048
  },
15984
18049
  "chats:admin": {
@@ -16546,6 +18611,50 @@ function getRevisionState(workflow, revision) {
16546
18611
  state: revision?.publishedAt != null ? "published" : "draft"
16547
18612
  };
16548
18613
  }
18614
+
18615
+ // src/helpers/chat-interaction.ts
18616
+ var ChatInteractionController = class {
18617
+ constructor(api, workspaceId, chatId) {
18618
+ this.api = api;
18619
+ this.workspaceId = workspaceId;
18620
+ this.chatId = chatId;
18621
+ }
18622
+ api;
18623
+ workspaceId;
18624
+ chatId;
18625
+ current;
18626
+ pending;
18627
+ tail = Promise.resolve();
18628
+ clientSessionId = crypto.randomUUID();
18629
+ /** Serialize switches and reuse request IDs when a response is lost. */
18630
+ ensure(mode) {
18631
+ const operation = this.tail.then(async () => {
18632
+ if (this.pending) await this.applyPending();
18633
+ if (this.current?.mode !== mode) {
18634
+ this.pending = { mode, requestId: crypto.randomUUID() };
18635
+ await this.applyPending();
18636
+ }
18637
+ if (!this.current) throw new Error("Interaction session unavailable");
18638
+ return this.current;
18639
+ });
18640
+ this.tail = operation.catch(() => void 0);
18641
+ return operation;
18642
+ }
18643
+ async applyPending() {
18644
+ const pending = this.pending;
18645
+ if (!pending) return;
18646
+ this.current = this.current ? await this.api.transitionChatInteractionSession(
18647
+ this.workspaceId,
18648
+ this.chatId,
18649
+ this.current.id,
18650
+ pending
18651
+ ) : await this.api.createChatInteractionSession(this.workspaceId, this.chatId, {
18652
+ ...pending,
18653
+ clientSessionId: this.clientSessionId
18654
+ });
18655
+ this.pending = void 0;
18656
+ }
18657
+ };
16549
18658
  // Annotate the CommonJS export names for ESM import in node:
16550
18659
  0 && (module.exports = {
16551
18660
  AGENT_NOTE_ORIGINS,
@@ -16556,6 +18665,16 @@ function getRevisionState(workflow, revision) {
16556
18665
  AccessGrantStatus,
16557
18666
  AccessGrantTrigger,
16558
18667
  AccessLevel,
18668
+ ActivityCapability,
18669
+ ActivityEventFamily,
18670
+ ActivityEventType,
18671
+ ActivityGrain,
18672
+ ActivityGroupBy,
18673
+ ActivityOpenItemOrder,
18674
+ ActivityOutcome,
18675
+ ActivityVisibility,
18676
+ ActivityWindowBasis,
18677
+ ActorKind,
16559
18678
  AgentBuilder,
16560
18679
  ApiError,
16561
18680
  ApplyError,
@@ -16576,8 +18695,15 @@ function getRevisionState(workflow, revision) {
16576
18695
  CalendarScheduleRecurrence,
16577
18696
  CalendarSource,
16578
18697
  CapabilityClass,
18698
+ ChannelMessageDirection,
18699
+ ChannelMessageSource,
18700
+ ChannelMessagesUnavailableReason,
18701
+ ChatInteractionController,
16579
18702
  ConsentMethod,
16580
18703
  CriterionType,
18704
+ DEFAULT_AGENT_CHAT_MODEL,
18705
+ DEFAULT_AGENT_REALTIME_MODEL,
18706
+ DEFAULT_AGENT_REALTIME_MODEL_CONFIG,
16581
18707
  DEFAULT_CHAT_MODEL,
16582
18708
  DEFAULT_CUSTOM_VOICE_MODEL,
16583
18709
  DEFAULT_THINKING_SPEECH_PHRASES,
@@ -16588,7 +18714,9 @@ function getRevisionState(workflow, revision) {
16588
18714
  DataSensitivity,
16589
18715
  DataTypeRecordScope,
16590
18716
  DriverMode,
18717
+ EhrWritebackOutcomeResponseStatus,
16591
18718
  EmailDnsRecordType,
18719
+ EntityKind,
16592
18720
  EventRuleActionType,
16593
18721
  EventRuleEventType,
16594
18722
  EventRuleObjectType,
@@ -16599,6 +18727,11 @@ function getRevisionState(workflow, revision) {
16599
18727
  FhirVendor,
16600
18728
  FormBuilder,
16601
18729
  GravityRailClient,
18730
+ ImportSkippedRuleResourceGroupResourceType,
18731
+ ImportSkippedRuleResponseNeededResourceTypesItem,
18732
+ ImportSkippedRuleResponseParentKind,
18733
+ ImportSkippedRuleResponseReasonCode,
18734
+ ImportSkippedRuleResponseStatus,
16602
18735
  InboundFaxStatusValues,
16603
18736
  IndexStatus,
16604
18737
  InvitationStatus,
@@ -16606,6 +18739,7 @@ function getRevisionState(workflow, revision) {
16606
18739
  JourneyBuilder,
16607
18740
  JourneyStepBuilder,
16608
18741
  MASKED_SECRET_SENTINEL,
18742
+ MEMBER_RELATIONSHIP_KINDS,
16609
18743
  McpServerState,
16610
18744
  MemberFeature,
16611
18745
  MemberFilterBuilder,
@@ -16613,6 +18747,7 @@ function getRevisionState(workflow, revision) {
16613
18747
  MemberImportPreviewRowAction,
16614
18748
  MemberImportValidationError,
16615
18749
  MemberLabelBuilder,
18750
+ MemberRelationshipKind,
16616
18751
  MemberType,
16617
18752
  MenuItemResponseItemType,
16618
18753
  MenuItemType,
@@ -16648,8 +18783,11 @@ function getRevisionState(workflow, revision) {
16648
18783
  REALTIME_MODEL_OPENAI,
16649
18784
  REALTIME_MODEL_OPENAI_2,
16650
18785
  REALTIME_MODEL_OPENAI_MINI,
18786
+ RefResolutionStatus,
16651
18787
  Region,
16652
18788
  RegistrationIdentifier,
18789
+ RelatedMemberRole,
18790
+ RelationshipCardinality,
16653
18791
  Resource,
16654
18792
  RoleUpdate,
16655
18793
  RoutineBuilder,
@@ -16674,7 +18812,12 @@ function getRevisionState(workflow, revision) {
16674
18812
  TTS_PREVIEW_PROVIDERS,
16675
18813
  TaskBuilder,
16676
18814
  TemplatesApi,
18815
+ TestChatRunLane,
18816
+ TestChatRunOutcome,
16677
18817
  ToolkitState,
18818
+ UiPromptPresentedKindValues,
18819
+ UiPromptResponseKindValues,
18820
+ UiPromptResponseStatusValues,
16678
18821
  WIDGET_SLUGS,
16679
18822
  WORKFLOW_IMPLICIT_USE_SCOPE,
16680
18823
  WorkflowAccessWarningResourceType,