@wayai/cli 0.3.219 → 0.3.220

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.
package/dist/index.js CHANGED
@@ -5283,25 +5283,6 @@ var init_chunk_VXEAR36B = __esm({
5283
5283
  }
5284
5284
  });
5285
5285
 
5286
- // ../../packages/core/dist/chunk-GPM7PE44.js
5287
- var bootstrapQuery;
5288
- var init_chunk_GPM7PE44 = __esm({
5289
- "../../packages/core/dist/chunk-GPM7PE44.js"() {
5290
- "use strict";
5291
- init_zod();
5292
- bootstrapQuery = external_exports.object({
5293
- active_hub_id: external_exports.string().uuid().optional(),
5294
- active_conversation_id: external_exports.string().uuid().optional(),
5295
- active_nav: external_exports.enum(["chat", "task", "support"]).optional(),
5296
- /**
5297
- * The people thread the URL names (`/chat/threads/:threadId`, gh #4661): the snapshot
5298
- * preloads it as `people.active_thread` when the viewer is a member.
5299
- */
5300
- active_thread_id: external_exports.string().uuid().optional()
5301
- });
5302
- }
5303
- });
5304
-
5305
5286
  // ../../packages/core/dist/chunk-VORPHGDT.js
5306
5287
  var PERMISSIONS;
5307
5288
  var init_chunk_VORPHGDT = __esm({
@@ -5517,34 +5498,6 @@ var init_chunk_ZVXO3XL6 = __esm({
5517
5498
  }
5518
5499
  });
5519
5500
 
5520
- // ../../packages/core/dist/chunk-ZXK6N2HN.js
5521
- var PEOPLE_MODERATION_NOTE_MAX_LENGTH, ADMIN_PEOPLE_REPORTS_PAGE_MAX, ADMIN_PEOPLE_REPORTS_PAGE_DEFAULT, PEOPLE_SUSPENDED_REASON, peopleModerationActionSchema, moderationNoteSchema, adminPeopleReportListQuery, adminPeopleReportIdParam, adminPeopleMessageRemovalBody, adminPeopleSuspendBody, adminPeopleNoteBody;
5522
- var init_chunk_ZXK6N2HN = __esm({
5523
- "../../packages/core/dist/chunk-ZXK6N2HN.js"() {
5524
- "use strict";
5525
- init_chunk_ZVXO3XL6();
5526
- init_chunk_HZ6CADSY();
5527
- init_zod();
5528
- PEOPLE_MODERATION_NOTE_MAX_LENGTH = 500;
5529
- ADMIN_PEOPLE_REPORTS_PAGE_MAX = 100;
5530
- ADMIN_PEOPLE_REPORTS_PAGE_DEFAULT = 50;
5531
- PEOPLE_SUSPENDED_REASON = "suspended";
5532
- peopleModerationActionSchema = external_exports.enum(["remove_message", "suspend", "unsuspend", "dismiss"]);
5533
- moderationNoteSchema = optionalTrimmedText(PEOPLE_MODERATION_NOTE_MAX_LENGTH);
5534
- adminPeopleReportListQuery = external_exports.object({
5535
- pending: external_exports.enum(["true", "false"]).optional().transform((value) => value === "true"),
5536
- /** Lower bound on `created_at`. */
5537
- since: timestampSchema.optional(),
5538
- limit: external_exports.coerce.number().int().min(1).max(ADMIN_PEOPLE_REPORTS_PAGE_MAX).default(ADMIN_PEOPLE_REPORTS_PAGE_DEFAULT),
5539
- offset: external_exports.coerce.number().int().min(0).default(0)
5540
- });
5541
- adminPeopleReportIdParam = external_exports.object({ reportId: uuidSchema });
5542
- adminPeopleMessageRemovalBody = external_exports.object({ report_id: uuidSchema, message_id: uuidSchema.optional(), note: moderationNoteSchema }).strict();
5543
- adminPeopleSuspendBody = external_exports.object({ report_id: uuidSchema.optional(), note: moderationNoteSchema }).strict();
5544
- adminPeopleNoteBody = external_exports.object({ note: moderationNoteSchema }).strict();
5545
- }
5546
- });
5547
-
5548
5501
  // ../../packages/core/dist/chunk-Y7CFCYX4.js
5549
5502
  var PEOPLE_REPORT_DETAILS_MAX_LENGTH, peopleReportReasonSchema, reportDetailsSchema, reportFields, peopleReportBody;
5550
5503
  var init_chunk_Y7CFCYX4 = __esm({
@@ -5947,57 +5900,21 @@ var init_chunk_IPDOHAZ5 = __esm({
5947
5900
  }
5948
5901
  });
5949
5902
 
5950
- // ../../packages/core/dist/chunk-SY6PLCPK.js
5951
- var jsonSchemaSchema, hubUserIdentity, stateValueEntry, getHubUserContextResponse, updateHubUserBody, updateHubUserResponse, unlockHubUserNameResponse, stateResetParams, stateResetResponse;
5952
- var init_chunk_SY6PLCPK = __esm({
5953
- "../../packages/core/dist/chunk-SY6PLCPK.js"() {
5903
+ // ../../packages/core/dist/chunk-GPM7PE44.js
5904
+ var bootstrapQuery;
5905
+ var init_chunk_GPM7PE44 = __esm({
5906
+ "../../packages/core/dist/chunk-GPM7PE44.js"() {
5954
5907
  "use strict";
5955
- init_chunk_6TSQ5HXC();
5956
5908
  init_zod();
5957
- jsonSchemaSchema = external_exports.record(external_exports.unknown());
5958
- hubUserIdentity = external_exports.object({
5959
- user_id: external_exports.string().nullable(),
5960
- user_name: external_exports.string().nullable(),
5961
- user_email: external_exports.string().nullable(),
5962
- user_name_locked: external_exports.boolean(),
5963
- created_at: external_exports.string(),
5964
- updated_at: external_exports.string().nullable(),
5965
- hub_user_id: external_exports.string().optional(),
5966
- enabled: external_exports.boolean().optional(),
5967
- hub_team_id: external_exports.string().nullable().optional(),
5968
- source: external_exports.enum(["grant", "auto"]).optional()
5969
- });
5970
- stateValueEntry = external_exports.object({
5971
- state_slug: external_exports.string(),
5972
- state_name: external_exports.string(),
5973
- state_description: external_exports.string().nullable().optional(),
5974
- scope: external_exports.enum(["user", "conversation"]),
5975
- json_schema: jsonSchemaSchema,
5976
- initial_value: external_exports.unknown(),
5977
- value: external_exports.unknown(),
5978
- is_reserved: external_exports.boolean()
5979
- });
5980
- getHubUserContextResponse = external_exports.object({
5981
- user: hubUserIdentity,
5982
- user_states: external_exports.array(stateValueEntry),
5983
- conversation_states: external_exports.array(stateValueEntry)
5984
- });
5985
- updateHubUserBody = external_exports.object({
5986
- // Non-empty, non-null. `.nullable()` here would bypass `.min(1)` and let an
5987
- // admin arm the lock on a null name — see hub-do.ts updateHubUser null-guard.
5988
- user_name: external_exports.string().min(1).max(120)
5989
- });
5990
- updateHubUserResponse = external_exports.object({
5991
- user: hubUserIdentity
5992
- });
5993
- unlockHubUserNameResponse = external_exports.object({
5994
- user: hubUserIdentity
5995
- });
5996
- stateResetParams = external_exports.object({
5997
- stateSlug: slugSchema
5998
- });
5999
- stateResetResponse = external_exports.object({
6000
- ok: external_exports.literal(true)
5909
+ bootstrapQuery = external_exports.object({
5910
+ active_hub_id: external_exports.string().uuid().optional(),
5911
+ active_conversation_id: external_exports.string().uuid().optional(),
5912
+ active_nav: external_exports.enum(["chat", "task", "support"]).optional(),
5913
+ /**
5914
+ * The people thread the URL names (`/chat/threads/:threadId`, gh #4661): the snapshot
5915
+ * preloads it as `people.active_thread` when the viewer is a member.
5916
+ */
5917
+ active_thread_id: external_exports.string().uuid().optional()
6001
5918
  });
6002
5919
  }
6003
5920
  });
@@ -6106,98 +6023,31 @@ var init_chunk_FPSDNS2E = __esm({
6106
6023
  }
6107
6024
  });
6108
6025
 
6109
- // ../../packages/core/dist/chunk-LKBSHANA.js
6110
- var DESKTOP_SHELL_VERSION_RE, DESKTOP_PLATFORMS, DESKTOP_FLAVORS, desktopShellInfoSchema, DESKTOP_PRESENCE_STATES, desktopPresenceSchema, desktopUpdateSchema, DESKTOP_SIGN_IN_URL_MAX_LENGTH, DESKTOP_APP_PATH_MAX_LENGTH, desktopAppPathSchema, DESKTOP_NOTIFICATION_KINDS, DESKTOP_NOTIFICATION_TITLE_MAX_LENGTH, DESKTOP_NOTIFICATION_BODY_MAX_LENGTH, notificationTitleSchema, notificationBodySchema, desktopNotificationSchema, DESKTOP_BADGE_MAX_COUNT, DESKTOP_BADGE_LABEL_MAX_LENGTH, desktopBadgeSchema, desktopNavigateSchema, desktopSettingsSchema, desktopSettingsChangeSchema, desktopBridgeArgsSchemas;
6111
- var init_chunk_LKBSHANA = __esm({
6112
- "../../packages/core/dist/chunk-LKBSHANA.js"() {
6026
+ // ../../packages/core/dist/chunk-ZXK6N2HN.js
6027
+ var PEOPLE_MODERATION_NOTE_MAX_LENGTH, ADMIN_PEOPLE_REPORTS_PAGE_MAX, ADMIN_PEOPLE_REPORTS_PAGE_DEFAULT, PEOPLE_SUSPENDED_REASON, peopleModerationActionSchema, moderationNoteSchema, adminPeopleReportListQuery, adminPeopleReportIdParam, adminPeopleMessageRemovalBody, adminPeopleSuspendBody, adminPeopleNoteBody;
6028
+ var init_chunk_ZXK6N2HN = __esm({
6029
+ "../../packages/core/dist/chunk-ZXK6N2HN.js"() {
6113
6030
  "use strict";
6031
+ init_chunk_ZVXO3XL6();
6032
+ init_chunk_HZ6CADSY();
6114
6033
  init_zod();
6115
- DESKTOP_SHELL_VERSION_RE = /^(0|[1-9]\d{0,5})\.(0|[1-9]\d{0,5})\.(0|[1-9]\d{0,5})(-[0-9A-Za-z.-]{1,32})?$/;
6116
- DESKTOP_PLATFORMS = ["darwin", "win32"];
6117
- DESKTOP_FLAVORS = ["production", "development"];
6118
- desktopShellInfoSchema = external_exports.object({
6119
- /** The shell's own release version, independent of the web deploy. */
6120
- shellVersion: external_exports.string().regex(DESKTOP_SHELL_VERSION_RE),
6121
- /** The Electron runtime the shell was built with. */
6122
- electronVersion: external_exports.string().regex(/^\d{1,4}\.\d{1,4}\.\d{1,4}(-[0-9A-Za-z.-]{1,32})?$/),
6123
- platform: external_exports.enum(DESKTOP_PLATFORMS),
6124
- /** CPU architecture as Node reports it (`arm64`, `x64`). */
6125
- arch: external_exports.string().regex(/^[a-z0-9_]{1,16}$/),
6126
- flavor: external_exports.enum(DESKTOP_FLAVORS),
6127
- /**
6128
- * Present, and true, when the shell runs from the Microsoft Store's package: the Store updates it,
6129
- * and Windows alone opens it at login (the package's startup task, which the person turns on in
6130
- * Windows' settings). An optional field, so no new `bridgeVersion`: an older page ignores it, and
6131
- * its absence is every other shell.
6132
- */
6133
- store: external_exports.literal(true).optional()
6134
- });
6135
- DESKTOP_PRESENCE_STATES = ["present", "away"];
6136
- desktopPresenceSchema = external_exports.object({
6137
- presence: external_exports.enum(DESKTOP_PRESENCE_STATES),
6138
- mainWindow: external_exports.object({
6139
- shown: external_exports.boolean(),
6140
- focused: external_exports.boolean()
6141
- })
6142
- });
6143
- desktopUpdateSchema = external_exports.object({
6144
- ready: external_exports.object({
6145
- version: external_exports.string().regex(DESKTOP_SHELL_VERSION_RE),
6146
- offerRestart: external_exports.boolean()
6147
- }).nullable()
6148
- });
6149
- DESKTOP_SIGN_IN_URL_MAX_LENGTH = 4096;
6150
- DESKTOP_APP_PATH_MAX_LENGTH = 512;
6151
- desktopAppPathSchema = external_exports.string().max(DESKTOP_APP_PATH_MAX_LENGTH).regex(/^\/(?![/\\])[^\s\\]*$/);
6152
- DESKTOP_NOTIFICATION_KINDS = ["handoff", "message", "summary"];
6153
- DESKTOP_NOTIFICATION_TITLE_MAX_LENGTH = 200;
6154
- DESKTOP_NOTIFICATION_BODY_MAX_LENGTH = 500;
6155
- notificationTitleSchema = external_exports.string().min(1).max(DESKTOP_NOTIFICATION_TITLE_MAX_LENGTH);
6156
- notificationBodySchema = external_exports.string().max(DESKTOP_NOTIFICATION_BODY_MAX_LENGTH);
6157
- desktopNotificationSchema = external_exports.object({
6158
- kind: external_exports.enum(DESKTOP_NOTIFICATION_KINDS),
6159
- title: notificationTitleSchema,
6160
- body: notificationBodySchema,
6161
- path: desktopAppPathSchema,
6162
- withoutPreview: external_exports.object({ title: notificationTitleSchema, body: notificationBodySchema }).optional()
6163
- });
6164
- DESKTOP_BADGE_MAX_COUNT = 1e6;
6165
- DESKTOP_BADGE_LABEL_MAX_LENGTH = 200;
6166
- desktopBadgeSchema = external_exports.object({
6167
- count: external_exports.number().int().min(0).max(DESKTOP_BADGE_MAX_COUNT),
6168
- label: external_exports.string().max(DESKTOP_BADGE_LABEL_MAX_LENGTH)
6169
- });
6170
- desktopNavigateSchema = external_exports.object({
6171
- path: desktopAppPathSchema
6172
- });
6173
- desktopSettingsSchema = external_exports.object({
6174
- /** The app opens when the person logs in to the computer: the operating system's own login item. */
6175
- openAtLogin: external_exports.boolean(),
6176
- /** Closing the window keeps the app running in the tray (true), or quits it (false). */
6177
- closeToTray: external_exports.boolean(),
6178
- /** The shell shows notifications (true), or none (false). The badge is not a notification. */
6179
- notifications: external_exports.boolean(),
6180
- /**
6181
- * A customer message's notification shows the customer's name and words, where the platform
6182
- * allows them at all (`desktopShowsCustomerWords`: macOS); elsewhere the shell never shows them.
6183
- */
6184
- messagePreview: external_exports.boolean()
6185
- });
6186
- desktopSettingsChangeSchema = desktopSettingsSchema.partial().strict().refine((change) => Object.values(change).every((value) => typeof value === "boolean"), {
6187
- message: "each setting changed is true or false"
6034
+ PEOPLE_MODERATION_NOTE_MAX_LENGTH = 500;
6035
+ ADMIN_PEOPLE_REPORTS_PAGE_MAX = 100;
6036
+ ADMIN_PEOPLE_REPORTS_PAGE_DEFAULT = 50;
6037
+ PEOPLE_SUSPENDED_REASON = "suspended";
6038
+ peopleModerationActionSchema = external_exports.enum(["remove_message", "suspend", "unsuspend", "dismiss"]);
6039
+ moderationNoteSchema = optionalTrimmedText(PEOPLE_MODERATION_NOTE_MAX_LENGTH);
6040
+ adminPeopleReportListQuery = external_exports.object({
6041
+ pending: external_exports.enum(["true", "false"]).optional().transform((value) => value === "true"),
6042
+ /** Lower bound on `created_at`. */
6043
+ since: timestampSchema.optional(),
6044
+ limit: external_exports.coerce.number().int().min(1).max(ADMIN_PEOPLE_REPORTS_PAGE_MAX).default(ADMIN_PEOPLE_REPORTS_PAGE_DEFAULT),
6045
+ offset: external_exports.coerce.number().int().min(0).default(0)
6188
6046
  });
6189
- desktopBridgeArgsSchemas = {
6190
- getShellInfo: external_exports.tuple([]),
6191
- getPresence: external_exports.tuple([]),
6192
- openSignIn: external_exports.tuple([external_exports.string().max(DESKTOP_SIGN_IN_URL_MAX_LENGTH)]),
6193
- getUpdate: external_exports.tuple([]),
6194
- restartToUpdate: external_exports.tuple([]),
6195
- notify: external_exports.tuple([desktopNotificationSchema]),
6196
- setBadge: external_exports.tuple([desktopBadgeSchema]),
6197
- clearAll: external_exports.tuple([]),
6198
- getSettings: external_exports.tuple([]),
6199
- setSettings: external_exports.tuple([desktopSettingsChangeSchema])
6200
- };
6047
+ adminPeopleReportIdParam = external_exports.object({ reportId: uuidSchema });
6048
+ adminPeopleMessageRemovalBody = external_exports.object({ report_id: uuidSchema, message_id: uuidSchema.optional(), note: moderationNoteSchema }).strict();
6049
+ adminPeopleSuspendBody = external_exports.object({ report_id: uuidSchema.optional(), note: moderationNoteSchema }).strict();
6050
+ adminPeopleNoteBody = external_exports.object({ note: moderationNoteSchema }).strict();
6201
6051
  }
6202
6052
  });
6203
6053
 
@@ -7582,58 +7432,58 @@ var init_chunk_EA23LSDS = __esm({
7582
7432
  }
7583
7433
  });
7584
7434
 
7585
- // ../../packages/core/dist/chunk-3O5XTDI2.js
7586
- var CONSULT_THREAD_STATUSES, consultThreadStatus, CONSULT_THREAD_TITLE_MAX, consultThreadTitle, consultThreadSummary, listConsultThreadsQuery, listConsultThreadsResponse, createConsultThreadBody, createConsultThreadResponse, consultThreadIdParam, updateConsultThreadBody, updateConsultThreadResponse, CONSULT_AWAIT_TIMEOUT_MS;
7587
- var init_chunk_3O5XTDI2 = __esm({
7588
- "../../packages/core/dist/chunk-3O5XTDI2.js"() {
7435
+ // ../../packages/core/dist/chunk-SY6PLCPK.js
7436
+ var jsonSchemaSchema, hubUserIdentity, stateValueEntry, getHubUserContextResponse, updateHubUserBody, updateHubUserResponse, unlockHubUserNameResponse, stateResetParams, stateResetResponse;
7437
+ var init_chunk_SY6PLCPK = __esm({
7438
+ "../../packages/core/dist/chunk-SY6PLCPK.js"() {
7589
7439
  "use strict";
7440
+ init_chunk_6TSQ5HXC();
7590
7441
  init_zod();
7591
- CONSULT_THREAD_STATUSES = ["open", "awaiting", "resolved", "cancelled_at_close"];
7592
- consultThreadStatus = external_exports.enum(CONSULT_THREAD_STATUSES);
7593
- CONSULT_THREAD_TITLE_MAX = 120;
7594
- consultThreadTitle = external_exports.string().trim().min(1).max(CONSULT_THREAD_TITLE_MAX);
7595
- consultThreadSummary = external_exports.object({
7596
- consult_thread_id: external_exports.string(),
7597
- conversation_id: external_exports.string(),
7598
- initiator_type: external_exports.enum(["team", "agent"]),
7599
- initiator_id: external_exports.string(),
7600
- engaged_agent_id: external_exports.string().nullable(),
7601
- engaged_agent_name: external_exports.string().nullable(),
7602
- title: external_exports.string().nullable(),
7603
- status: consultThreadStatus,
7604
- created_at: external_exports.string()
7442
+ jsonSchemaSchema = external_exports.record(external_exports.unknown());
7443
+ hubUserIdentity = external_exports.object({
7444
+ user_id: external_exports.string().nullable(),
7445
+ user_name: external_exports.string().nullable(),
7446
+ user_email: external_exports.string().nullable(),
7447
+ user_name_locked: external_exports.boolean(),
7448
+ created_at: external_exports.string(),
7449
+ updated_at: external_exports.string().nullable(),
7450
+ hub_user_id: external_exports.string().optional(),
7451
+ enabled: external_exports.boolean().optional(),
7452
+ hub_team_id: external_exports.string().nullable().optional(),
7453
+ source: external_exports.enum(["grant", "auto"]).optional()
7605
7454
  });
7606
- listConsultThreadsQuery = external_exports.object({
7607
- hub_id: external_exports.string().uuid()
7455
+ stateValueEntry = external_exports.object({
7456
+ state_slug: external_exports.string(),
7457
+ state_name: external_exports.string(),
7458
+ state_description: external_exports.string().nullable().optional(),
7459
+ scope: external_exports.enum(["user", "conversation"]),
7460
+ json_schema: jsonSchemaSchema,
7461
+ initial_value: external_exports.unknown(),
7462
+ value: external_exports.unknown(),
7463
+ is_reserved: external_exports.boolean()
7608
7464
  });
7609
- listConsultThreadsResponse = external_exports.object({
7610
- threads: external_exports.array(consultThreadSummary)
7465
+ getHubUserContextResponse = external_exports.object({
7466
+ user: hubUserIdentity,
7467
+ user_states: external_exports.array(stateValueEntry),
7468
+ conversation_states: external_exports.array(stateValueEntry)
7611
7469
  });
7612
- createConsultThreadBody = external_exports.object({
7613
- hub_id: external_exports.string().uuid(),
7614
- title: consultThreadTitle.optional(),
7615
- // Optionally engage a consultant on creation. Validated server-side against the
7616
- // hub's `consultant`-role agents; a non-consultant / unknown id is rejected.
7617
- engaged_agent_id: external_exports.string().uuid().optional()
7470
+ updateHubUserBody = external_exports.object({
7471
+ // Non-empty, non-null. `.nullable()` here would bypass `.min(1)` and let an
7472
+ // admin arm the lock on a null name — see hub-do.ts updateHubUser null-guard.
7473
+ user_name: external_exports.string().min(1).max(120)
7618
7474
  });
7619
- createConsultThreadResponse = external_exports.object({
7620
- thread: consultThreadSummary
7475
+ updateHubUserResponse = external_exports.object({
7476
+ user: hubUserIdentity
7621
7477
  });
7622
- consultThreadIdParam = external_exports.object({
7623
- id: external_exports.string().uuid(),
7624
- threadId: external_exports.string().uuid()
7478
+ unlockHubUserNameResponse = external_exports.object({
7479
+ user: hubUserIdentity
7625
7480
  });
7626
- updateConsultThreadBody = external_exports.object({
7627
- hub_id: external_exports.string().uuid(),
7628
- title: consultThreadTitle.optional(),
7629
- engaged_agent_id: external_exports.string().uuid().optional()
7630
- }).refine((v) => v.title !== void 0 || v.engaged_agent_id !== void 0, {
7631
- message: "Provide a title and/or an engaged_agent_id to update"
7481
+ stateResetParams = external_exports.object({
7482
+ stateSlug: slugSchema
7632
7483
  });
7633
- updateConsultThreadResponse = external_exports.object({
7634
- thread: consultThreadSummary
7484
+ stateResetResponse = external_exports.object({
7485
+ ok: external_exports.literal(true)
7635
7486
  });
7636
- CONSULT_AWAIT_TIMEOUT_MS = 15 * 6e4;
7637
7487
  }
7638
7488
  });
7639
7489
 
@@ -7694,15 +7544,15 @@ var init_chunk_MH4O3YEX = __esm({
7694
7544
  }
7695
7545
  });
7696
7546
 
7697
- // ../../packages/core/dist/chunk-VBUWGVFY.js
7547
+ // ../../packages/core/dist/chunk-QCQUZL4L.js
7698
7548
  function catalogToolSideEffects(toolName) {
7699
7549
  const sideEffects = CATALOG_SIDE_EFFECTS.get(toolName);
7700
7550
  if (sideEffects === void 0) return "unknown";
7701
7551
  return sideEffects ? "side_effects" : "none";
7702
7552
  }
7703
7553
  var NATIVE_TOOL_SCHEMAS, WAYAI_CONNECTOR, SANDBOX_AGENT_ROLES, BASE_NATIVE_TOOLS, NATIVE_TOOLS, CATALOG_SIDE_EFFECTS;
7704
- var init_chunk_VBUWGVFY = __esm({
7705
- "../../packages/core/dist/chunk-VBUWGVFY.js"() {
7554
+ var init_chunk_QCQUZL4L = __esm({
7555
+ "../../packages/core/dist/chunk-QCQUZL4L.js"() {
7706
7556
  "use strict";
7707
7557
  init_chunk_DHPUPI4Y();
7708
7558
  NATIVE_TOOL_SCHEMAS = {
@@ -8582,8 +8432,8 @@ var init_chunk_VBUWGVFY = __esm({
8582
8432
  SANDBOX_AGENT_ROLES = [...PILOT_TRACK_ROLES, ...COPILOT_TRACK_ROLES];
8583
8433
  BASE_NATIVE_TOOLS = [
8584
8434
  // --- Wayai core tools ---
8585
- { tool_native_id: "nt-001", tool_name: "transfer_to_agent", tool_display_name: "Transfer to Agent", tool_description: "Transfer the conversation to another AI agent", connector_id: WAYAI_CONNECTOR, operation: "transfer_to_agent", tool_method: "internal", tool_group: "Native Tools", is_delegation: true, is_auto_set: false, execution_config: null, side_effects: false, replay: "reconcile" },
8586
- { tool_native_id: "nt-002", tool_name: "transfer_to_team", tool_display_name: "Transfer to Team", tool_description: "Escalate conversation to a human support team", connector_id: WAYAI_CONNECTOR, operation: "transfer_to_team", tool_method: "internal", tool_group: "Native Tools", is_delegation: true, is_auto_set: false, execution_config: null, side_effects: false, replay: "reconcile" },
8435
+ { tool_native_id: "nt-001", tool_name: "transfer_to_agent", tool_display_name: "Transfer to Agent", tool_description: "Transfer the conversation to another AI agent", connector_id: WAYAI_CONNECTOR, operation: "transfer_to_agent", tool_method: "internal", tool_group: "Native Tools", is_delegation: true, is_auto_set: false, execution_config: null, side_effects: false, replay: "keyed" },
8436
+ { tool_native_id: "nt-002", tool_name: "transfer_to_team", tool_display_name: "Transfer to Team", tool_description: "Escalate conversation to a human support team", connector_id: WAYAI_CONNECTOR, operation: "transfer_to_team", tool_method: "internal", tool_group: "Native Tools", is_delegation: true, is_auto_set: false, execution_config: null, side_effects: false, replay: "keyed" },
8587
8437
  { tool_native_id: "nt-003", tool_name: "close_conversation", tool_display_name: "Close Conversation", tool_description: "Close and end the current conversation", connector_id: WAYAI_CONNECTOR, operation: "close_conversation", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: true, replay: "keyed" },
8588
8438
  { tool_native_id: "nt-004", tool_name: "update_kanban_status", tool_display_name: "Update Kanban Status", tool_description: "Update the kanban status of the conversation", connector_id: WAYAI_CONNECTOR, operation: "update_kanban_status", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, side_effects: false, replay: "rerun" },
8589
8439
  { tool_native_id: "nt-005", tool_name: "schedule_followup", tool_display_name: "Schedule Follow-up", tool_description: "Schedule a follow-up message for the conversation", connector_id: WAYAI_CONNECTOR, operation: "schedule_followup", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: true, execution_config: null, side_effects: true, replay: "keyed" },
@@ -8914,7 +8764,7 @@ var init_chunk_T7KQKDET = __esm({
8914
8764
  }
8915
8765
  });
8916
8766
 
8917
- // ../../packages/core/dist/chunk-6WCPZ26B.js
8767
+ // ../../packages/core/dist/chunk-BQWVW6JO.js
8918
8768
  function resolveMonitorTrigger(monitorConfig) {
8919
8769
  if (!monitorConfig || typeof monitorConfig !== "object") return "idle";
8920
8770
  const raw = monitorConfig.trigger;
@@ -9220,10 +9070,10 @@ function refineMonitorRulesStructuredOutput(body, ctx) {
9220
9070
  if (refusal2) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["response_format"], message: refusal2 });
9221
9071
  }
9222
9072
  var NATIVE_TOOL_NAMES, previousConversationsCountField, summarizationThresholdField, flagConditionSchema, MONITOR_TRIGGERS, monitorTriggerSchema, AUTOMATION_GATE_TRIGGERS, NON_FIRING_TRIGGERS, MONITOR_FIRING_TRIGGERS, MONITOR_DELAY_SECONDS_MIN, MONITOR_IDLE_DELAY_REQUIRED_MESSAGE, MONITOR_HISTORY_MESSAGES_MAX, monitorHistoryMessagesSchema, monitorIncludeToolResultsSchema, MONITOR_INPUT_SHAPING_KEYS, MONITOR_INPUT_SHAPING_SCHEMAS, MONITOR_INPUT_SHAPING_IDLE_MESSAGE, monitorArgumentSourceSchema, MONITOR_NOTE_TEMPLATE_MAX, MONITOR_STEER_NOTE_MAX, MONITOR_GATE_AGENT_NAME_MAX, monitorActionSchema, monitorRuleSchema, MONITOR_RULE_KEYS, MONITOR_RULE_SCHEMAS, MONITOR_RULE_TRIGGERS, MONITOR_RULE_TRIGGER_MESSAGE, CALL_UTTERANCE_SPEAKERS, callUtteranceSpeakerSchema, MONITOR_CALL_KEYS, MONITOR_CALL_SCHEMAS, MONITOR_CALL_KEY_MESSAGE, CALL_STEERING_MIN_CONFIDENCE, CALL_UTTERANCE_RULE_NOT_CONFIDENT_MESSAGE, CALL_UTTERANCE_FALLBACK_MESSAGE, CALL_UTTERANCE_FLAG_CONDITIONS_MESSAGE, CALL_STEER_NOTE_BLANK_MESSAGE, MONITOR_USER_MESSAGE_ACTION_KINDS, MONITOR_ASSISTANT_REPLY_ACTION_KINDS, MONITOR_CALL_UTTERANCE_ACTION_KINDS, MONITOR_AUTOMATION_FIRE_ACTION_KINDS, MONITOR_AUTOMATION_ITEM_ACTION_KINDS, INSERT_NOTE_TOOL_NAME, RUN_MONITOR_TOOL_NAME, MONITOR_RULE_ALLOWED_NATIVE_TOOLS, MONITOR_RULE_REENTRY_TOOLS, MONITOR_RULE_REENTRY_TRACKS, AUTOMATION_FIRE_FLAG_CONDITIONS_MESSAGE, AUTOMATION_FIRE_INPUT_SHAPING_MESSAGE, AUTOMATION_ITEM_FLAG_CONDITIONS_MESSAGE, AUTOMATION_ITEM_INPUT_SHAPING_MESSAGE, AUTOMATION_GATE_KEY_MESSAGES, monitorConfigField, flagConditionsField, agentIdParam, listAgentsQuery, agentConnectionsQuery, createAgentBody, updateAgentBody, AGENT_PARAMETER_TYPES, AGENT_PARAMETER_NAME_REGEX, agentParameterCreateSchema, MAX_AGENT_PARAMETERS_PER_REQUEST, createAgentParametersBody;
9223
- var init_chunk_6WCPZ26B = __esm({
9224
- "../../packages/core/dist/chunk-6WCPZ26B.js"() {
9073
+ var init_chunk_BQWVW6JO = __esm({
9074
+ "../../packages/core/dist/chunk-BQWVW6JO.js"() {
9225
9075
  "use strict";
9226
- init_chunk_VBUWGVFY();
9076
+ init_chunk_QCQUZL4L();
9227
9077
  init_chunk_IBL7FANV();
9228
9078
  init_chunk_PFDZEKDE();
9229
9079
  init_chunk_HZ6CADSY();
@@ -9446,12 +9296,12 @@ var init_chunk_6WCPZ26B = __esm({
9446
9296
  }
9447
9297
  });
9448
9298
 
9449
- // ../../packages/core/dist/chunk-YVHDDEQV.js
9299
+ // ../../packages/core/dist/chunk-SPE6FAYO.js
9450
9300
  var conversationIdParam, conversationHubQuery, claimBody, releaseBody, transferBody, closeBody, additionalContextPayloadSchema, kanbanUpdateBody, annotateConversationBody, observabilityParams, observabilityListParams, deleteUserConversationsBody, deleteUserConversationsResponse, sendMessageBody, listConversationsQuery, flagSourceSchema, getConversationsResponse, getConversationDetailParams, getConversationDetailQuery, getConversationDetailResponse, listWhatsAppTemplatesQuery, sendWhatsAppTemplateBody;
9451
- var init_chunk_YVHDDEQV = __esm({
9452
- "../../packages/core/dist/chunk-YVHDDEQV.js"() {
9301
+ var init_chunk_SPE6FAYO = __esm({
9302
+ "../../packages/core/dist/chunk-SPE6FAYO.js"() {
9453
9303
  "use strict";
9454
- init_chunk_6WCPZ26B();
9304
+ init_chunk_BQWVW6JO();
9455
9305
  init_chunk_HZ6CADSY();
9456
9306
  init_chunk_DHPUPI4Y();
9457
9307
  init_zod();
@@ -9748,115 +9598,98 @@ var init_chunk_KSTYTQ7I = __esm({
9748
9598
  }
9749
9599
  });
9750
9600
 
9751
- // ../../packages/core/dist/chunk-7CYHPF35.js
9752
- var appMessageSenderType, appMessageReceiverType, apiChannelMessage, apiChannelMessageBody, appMessageBody, appMessageResponse;
9753
- var init_chunk_7CYHPF35 = __esm({
9754
- "../../packages/core/dist/chunk-7CYHPF35.js"() {
9601
+ // ../../packages/core/dist/chunk-LKBSHANA.js
9602
+ var DESKTOP_SHELL_VERSION_RE, DESKTOP_PLATFORMS, DESKTOP_FLAVORS, desktopShellInfoSchema, DESKTOP_PRESENCE_STATES, desktopPresenceSchema, desktopUpdateSchema, DESKTOP_SIGN_IN_URL_MAX_LENGTH, DESKTOP_APP_PATH_MAX_LENGTH, desktopAppPathSchema, DESKTOP_NOTIFICATION_KINDS, DESKTOP_NOTIFICATION_TITLE_MAX_LENGTH, DESKTOP_NOTIFICATION_BODY_MAX_LENGTH, notificationTitleSchema, notificationBodySchema, desktopNotificationSchema, DESKTOP_BADGE_MAX_COUNT, DESKTOP_BADGE_LABEL_MAX_LENGTH, desktopBadgeSchema, desktopNavigateSchema, desktopSettingsSchema, desktopSettingsChangeSchema, desktopBridgeArgsSchemas;
9603
+ var init_chunk_LKBSHANA = __esm({
9604
+ "../../packages/core/dist/chunk-LKBSHANA.js"() {
9755
9605
  "use strict";
9756
- init_chunk_HZ6CADSY();
9757
9606
  init_zod();
9758
- appMessageSenderType = external_exports.enum(["user", "team"]);
9759
- appMessageReceiverType = external_exports.enum(["user", "team", "agent", "assistant"]).transform((v) => v === "assistant" ? "agent" : v);
9760
- apiChannelMessage = external_exports.object({
9761
- text: clientOptionalString,
9762
- attachments: external_exports.array(messageAttachment).max(MAX_ATTACHMENTS_PER_MESSAGE).nullish().transform((v) => v ?? void 0)
9763
- }).refine((m) => m.text && m.text.length > 0 || m.attachments && m.attachments.length > 0, {
9764
- message: "message must have text or at least one attachment"
9607
+ DESKTOP_SHELL_VERSION_RE = /^(0|[1-9]\d{0,5})\.(0|[1-9]\d{0,5})\.(0|[1-9]\d{0,5})(-[0-9A-Za-z.-]{1,32})?$/;
9608
+ DESKTOP_PLATFORMS = ["darwin", "win32"];
9609
+ DESKTOP_FLAVORS = ["production", "development"];
9610
+ desktopShellInfoSchema = external_exports.object({
9611
+ /** The shell's own release version, independent of the web deploy. */
9612
+ shellVersion: external_exports.string().regex(DESKTOP_SHELL_VERSION_RE),
9613
+ /** The Electron runtime the shell was built with. */
9614
+ electronVersion: external_exports.string().regex(/^\d{1,4}\.\d{1,4}\.\d{1,4}(-[0-9A-Za-z.-]{1,32})?$/),
9615
+ platform: external_exports.enum(DESKTOP_PLATFORMS),
9616
+ /** CPU architecture as Node reports it (`arm64`, `x64`). */
9617
+ arch: external_exports.string().regex(/^[a-z0-9_]{1,16}$/),
9618
+ flavor: external_exports.enum(DESKTOP_FLAVORS),
9619
+ /**
9620
+ * Present, and true, when the shell runs from the Microsoft Store's package: the Store updates it,
9621
+ * and Windows alone opens it at login (the package's startup task, which the person turns on in
9622
+ * Windows' settings). An optional field, so no new `bridgeVersion`: an older page ignores it, and
9623
+ * its absence is every other shell.
9624
+ */
9625
+ store: external_exports.literal(true).optional()
9765
9626
  });
9766
- apiChannelMessageBody = external_exports.object({
9767
- // Correlation id (task hubs): new → new conversation, repeat → continue. min 1 so an
9768
- // empty string can't masquerade as a ref. Mutually exclusive with conversation_id.
9769
- external_ref: external_exports.string().min(1).max(256).optional(),
9770
- // Continue a specific WayAI conversation (authorized against the hub/channel + owner).
9771
- // UUID-validated here (unlike the app channel, whose client we control): allocation
9772
- // only treats a UUID-shaped id as a provided conversation, so a malformed id would
9773
- // otherwise skip the owner guard and silently MINT a new conversation instead of
9774
- // rejecting. A format 400 is shape-only — not an existence oracle (a valid-but-unknown
9775
- // UUID still collapses to the opaque authorization error downstream).
9776
- conversation_id: external_exports.string().uuid().optional(),
9777
- // On-behalf-of end-user identity. Absent → per-connection service principal (task-hub
9778
- // only; chat hub rejects with 422 in the route).
9779
- user: external_exports.object({
9780
- id: external_exports.string().min(1),
9781
- email: clientOptionalString,
9782
- name: clientOptionalString
9783
- }).optional(),
9784
- message: apiChannelMessage,
9785
- // Idempotency key: maps to channel_message_sid, deduped within one conversation
9786
- // (ConversationDO.storeMessage). A retried POST resolves to the same conversation (a chat
9787
- // hub's user, the external_ref, the conversation_id, or on a task hub with neither, this key
9788
- // scoped by the sender), so it echoes the original message_id and skips billing / turn
9789
- // dispatch. A failed store answers a retryable 503 only when this key is set; without it a
9790
- // retry could store the message twice, so it answers 400.
9791
- client_message_id: external_exports.string().min(1).max(256).optional()
9792
- }).refine((b) => !(b.external_ref && b.conversation_id), {
9793
- message: "provide external_ref or conversation_id, not both",
9794
- path: ["external_ref"]
9627
+ DESKTOP_PRESENCE_STATES = ["present", "away"];
9628
+ desktopPresenceSchema = external_exports.object({
9629
+ presence: external_exports.enum(DESKTOP_PRESENCE_STATES),
9630
+ mainWindow: external_exports.object({
9631
+ shown: external_exports.boolean(),
9632
+ focused: external_exports.boolean()
9633
+ })
9795
9634
  });
9796
- appMessageBody = external_exports.object({
9797
- // Message content — three historical aliases. All optional: an attachment-only
9798
- // or voice-only message carries no text.
9799
- content: clientOptionalString,
9800
- message_text: clientOptionalString,
9801
- message_body: clientOptionalString,
9802
- // Conversation context. Ids are plain strings rather than `.uuid()` on purpose:
9803
- // they are AUTHORIZED downstream, which is the stronger guarantee — a well-formed
9804
- // uuid belonging to another tenant must fail just as hard as junk. `hub_id` is
9805
- // gated by `assertHubEndUserAccess` (gh #3286) and `conversation_id` by HubDO's
9806
- // conversation_index owner check (gh #2781, #3281). The route's own falsy guards
9807
- // ('hub_id is required') still reject an empty one.
9808
- hub_id: clientOptionalString,
9809
- channel_id: clientOptionalString,
9810
- conversation_id: clientOptionalString,
9811
- hub_type: external_exports.enum(["chat", "task"]).nullish().transform((v) => v ?? void 0),
9812
- // Stable idempotency key for one explicit task-hub launcher. HubDO scopes it
9813
- // to the authenticated user and resolves retries/tabs to one conversation.
9814
- task_start_id: external_exports.string().uuid().nullish().transform((v) => v ?? void 0),
9815
- // Routing.
9816
- sender_type: appMessageSenderType.nullish().transform((v) => v ?? void 0),
9817
- receiver_type: appMessageReceiverType.nullish().transform((v) => v ?? void 0),
9818
- // Only meaningful on a team send, where `validateAppTeamSendContext` proves the
9819
- // caller may send to this receiver. Absent on a team send to a conversation with no
9820
- // person, which names its `conversation_id` instead. The end-user branch ignores it —
9821
- // see the receiver derivation in the route.
9822
- user_receiver_id: clientOptionalString,
9823
- // ── Internal consult (consultant-agents PR 2 — H1.0) ──────────────────────
9824
- // A team member handling a customer conversation can tag a `consultant`-role
9825
- // agent for a PRIVATE, team-only exchange that never reaches the customer. A
9826
- // consult send is a team send with `receiver_type: 'agent'` targeting the
9827
- // consultant; `user_receiver_id` identifies the customer whose conversation this is
9828
- // (and is authorized by `validateAppTeamSendContext`, exactly as a team→user send is),
9829
- // and is absent, as on a team→user send, when the conversation has no person. The consultant is resolved from `agent_receiver_id`
9830
- // when supplied, else from an `@mention` parsed out of the message text against
9831
- // the hub's consultant agents. `consult_thread_id` continues an existing thread;
9832
- // absent, the route creates/reuses the single implicit thread. These fields are
9833
- // inert on every non-consult send (end-user send, team→user send).
9834
- agent_receiver_id: clientOptionalString,
9835
- consult_thread_id: clientOptionalString,
9836
- is_first_message: clientOptionalBoolean,
9837
- end_conversation: clientOptionalBoolean,
9838
- // Pre-generated by the client so the optimistic bubble and the stored row share
9839
- // a key (transcription live-updates land on the same row instead of duplicating).
9840
- message_id: clientOptionalString,
9841
- attachments: external_exports.array(messageAttachment).max(MAX_ATTACHMENTS_PER_MESSAGE).nullish().transform((v) => v ?? void 0),
9842
- // Base64-encoded audio for STT. Size-capped in the route (the cap is a byte
9843
- // budget tied to the /channels/* bodyLimit, not a shape rule).
9844
- audio_file: clientOptionalString
9635
+ desktopUpdateSchema = external_exports.object({
9636
+ ready: external_exports.object({
9637
+ version: external_exports.string().regex(DESKTOP_SHELL_VERSION_RE),
9638
+ offerRestart: external_exports.boolean()
9639
+ }).nullable()
9845
9640
  });
9846
- appMessageResponse = external_exports.object({
9847
- success: external_exports.boolean(),
9848
- message: external_exports.string(),
9849
- result: external_exports.object({
9850
- conversation_id: external_exports.string().optional(),
9851
- message_id: external_exports.string().optional(),
9852
- status: external_exports.string().optional(),
9853
- files: external_exports.array(external_exports.record(external_exports.string(), external_exports.unknown())).optional(),
9854
- // True when this request reused a task-start/message id already accepted by
9855
- // the server. Clients must replace their optimistic payload with a fresh
9856
- // authoritative read because another tab may have won with different text.
9857
- deduped: external_exports.boolean().optional()
9858
- }).optional()
9641
+ DESKTOP_SIGN_IN_URL_MAX_LENGTH = 4096;
9642
+ DESKTOP_APP_PATH_MAX_LENGTH = 512;
9643
+ desktopAppPathSchema = external_exports.string().max(DESKTOP_APP_PATH_MAX_LENGTH).regex(/^\/(?![/\\])[^\s\\]*$/);
9644
+ DESKTOP_NOTIFICATION_KINDS = ["handoff", "message", "summary"];
9645
+ DESKTOP_NOTIFICATION_TITLE_MAX_LENGTH = 200;
9646
+ DESKTOP_NOTIFICATION_BODY_MAX_LENGTH = 500;
9647
+ notificationTitleSchema = external_exports.string().min(1).max(DESKTOP_NOTIFICATION_TITLE_MAX_LENGTH);
9648
+ notificationBodySchema = external_exports.string().max(DESKTOP_NOTIFICATION_BODY_MAX_LENGTH);
9649
+ desktopNotificationSchema = external_exports.object({
9650
+ kind: external_exports.enum(DESKTOP_NOTIFICATION_KINDS),
9651
+ title: notificationTitleSchema,
9652
+ body: notificationBodySchema,
9653
+ path: desktopAppPathSchema,
9654
+ withoutPreview: external_exports.object({ title: notificationTitleSchema, body: notificationBodySchema }).optional()
9655
+ });
9656
+ DESKTOP_BADGE_MAX_COUNT = 1e6;
9657
+ DESKTOP_BADGE_LABEL_MAX_LENGTH = 200;
9658
+ desktopBadgeSchema = external_exports.object({
9659
+ count: external_exports.number().int().min(0).max(DESKTOP_BADGE_MAX_COUNT),
9660
+ label: external_exports.string().max(DESKTOP_BADGE_LABEL_MAX_LENGTH)
9661
+ });
9662
+ desktopNavigateSchema = external_exports.object({
9663
+ path: desktopAppPathSchema
9859
9664
  });
9665
+ desktopSettingsSchema = external_exports.object({
9666
+ /** The app opens when the person logs in to the computer: the operating system's own login item. */
9667
+ openAtLogin: external_exports.boolean(),
9668
+ /** Closing the window keeps the app running in the tray (true), or quits it (false). */
9669
+ closeToTray: external_exports.boolean(),
9670
+ /** The shell shows notifications (true), or none (false). The badge is not a notification. */
9671
+ notifications: external_exports.boolean(),
9672
+ /**
9673
+ * A customer message's notification shows the customer's name and words, where the platform
9674
+ * allows them at all (`desktopShowsCustomerWords`: macOS); elsewhere the shell never shows them.
9675
+ */
9676
+ messagePreview: external_exports.boolean()
9677
+ });
9678
+ desktopSettingsChangeSchema = desktopSettingsSchema.partial().strict().refine((change) => Object.values(change).every((value) => typeof value === "boolean"), {
9679
+ message: "each setting changed is true or false"
9680
+ });
9681
+ desktopBridgeArgsSchemas = {
9682
+ getShellInfo: external_exports.tuple([]),
9683
+ getPresence: external_exports.tuple([]),
9684
+ openSignIn: external_exports.tuple([external_exports.string().max(DESKTOP_SIGN_IN_URL_MAX_LENGTH)]),
9685
+ getUpdate: external_exports.tuple([]),
9686
+ restartToUpdate: external_exports.tuple([]),
9687
+ notify: external_exports.tuple([desktopNotificationSchema]),
9688
+ setBadge: external_exports.tuple([desktopBadgeSchema]),
9689
+ clearAll: external_exports.tuple([]),
9690
+ getSettings: external_exports.tuple([]),
9691
+ setSettings: external_exports.tuple([desktopSettingsChangeSchema])
9692
+ };
9860
9693
  }
9861
9694
  });
9862
9695
 
@@ -9924,7 +9757,7 @@ var init_chunk_BPCNB5RT = __esm({
9924
9757
  }
9925
9758
  });
9926
9759
 
9927
- // ../../packages/core/dist/chunk-5KFFZX2J.js
9760
+ // ../../packages/core/dist/chunk-LM3FU67F.js
9928
9761
  function idempotencyHeaderRefusal(value) {
9929
9762
  if (typeof value !== "string" || !/^[A-Za-z0-9][A-Za-z0-9-]{0,63}$/.test(value)) {
9930
9763
  return "idempotency_header must be a header name: letters, digits and dashes, at most 64";
@@ -9935,10 +9768,10 @@ function idempotencyHeaderRefusal(value) {
9935
9768
  return null;
9936
9769
  }
9937
9770
  var CATALOG_REPLAY, REPLAY_OVERRIDES, RESERVED_HEADERS;
9938
- var init_chunk_5KFFZX2J = __esm({
9939
- "../../packages/core/dist/chunk-5KFFZX2J.js"() {
9771
+ var init_chunk_LM3FU67F = __esm({
9772
+ "../../packages/core/dist/chunk-LM3FU67F.js"() {
9940
9773
  "use strict";
9941
- init_chunk_VBUWGVFY();
9774
+ init_chunk_QCQUZL4L();
9942
9775
  CATALOG_REPLAY = new Map(
9943
9776
  NATIVE_TOOLS.map((tool) => [tool.tool_name, tool.replay])
9944
9777
  );
@@ -10171,7 +10004,7 @@ var init_chunk_WEXVYJ5H = __esm({
10171
10004
  }
10172
10005
  });
10173
10006
 
10174
- // ../../packages/core/dist/chunk-D26NGKIY.js
10007
+ // ../../packages/core/dist/chunk-GEYJNCIJ.js
10175
10008
  function refineToolConfig(value, ctx) {
10176
10009
  const raw = value.tool_config;
10177
10010
  if (raw == null) return;
@@ -10207,10 +10040,10 @@ function refineToolConfig(value, ctx) {
10207
10040
  }
10208
10041
  }
10209
10042
  var toolIdParam, listToolsQuery, toolAgentQuery, deleteToolQuery, toolConnectionsQuery, nativeToolIdSchema, CONTEXT_BOUNDARIES, contextBoundarySchema, addNativeToolBody, addMcpToolBody, toolReplaySettingsFields, toolReplaySettingsSchema, createCustomToolBody, updateCustomToolBody, updateToolExecutionConfigBody;
10210
- var init_chunk_D26NGKIY = __esm({
10211
- "../../packages/core/dist/chunk-D26NGKIY.js"() {
10043
+ var init_chunk_GEYJNCIJ = __esm({
10044
+ "../../packages/core/dist/chunk-GEYJNCIJ.js"() {
10212
10045
  "use strict";
10213
- init_chunk_5KFFZX2J();
10046
+ init_chunk_LM3FU67F();
10214
10047
  init_chunk_WEXVYJ5H();
10215
10048
  init_chunk_HZ6CADSY();
10216
10049
  init_zod();
@@ -11582,7 +11415,7 @@ var init_chunk_6NI5RAM4 = __esm({
11582
11415
  }
11583
11416
  });
11584
11417
 
11585
- // ../../packages/core/dist/chunk-DBQLPVOO.js
11418
+ // ../../packages/core/dist/chunk-54QBGDXF.js
11586
11419
  function refineHubAsCodeCustomTools(config, ctx) {
11587
11420
  const agents = config.agents;
11588
11421
  if (!Array.isArray(agents)) return;
@@ -12110,12 +11943,12 @@ function refineHubAsCodeMonitorRulesOutput(config, ctx) {
12110
11943
  });
12111
11944
  }
12112
11945
  var MAX_10MB_BASE64_ENCODED_BYTES, MAX_EVAL_ATTACHMENT_ENCODED_BYTES, MAX_EVAL_ATTACHMENT_CARRIERS, MAX_EVAL_ATTACHMENT_AGGREGATE_ENCODED_BYTES, MAX_RESOURCE_ENCODED_BYTES, MAX_HUB_AS_CODE_RESOURCES, MAX_HUB_AS_CODE_RESOURCE_FILES, MAX_RESOURCE_AGGREGATE_ENCODED_BYTES, MAX_CI_CONFIG_BODY_BYTES, MAX_CALL_OPENING_CARRIERS, MAX_CALL_OPENING_AGGREGATE_ENCODED_BYTES, hubAsCodeStateSchema, hubAsCodeResourceFileSchema, hubAsCodeResourceSchema, uuidPattern, ciUuidSchema, boundedHubAsCodeResourcesSchema, hubAsCodeConfigSchema, ciPullHubIdParam, ciBranchParam, ciPullQuery, ciHubsQuery, ciLookupQuery, ciBranchesQuery, ciSyncBody, ciPushBody, ciDiffBody, ciPublishBody, ciPublishPreviewBody, ciSyncMcpBody, ciOrgResourcesParam, orgResourcesConfigSchema, ciOrgResourcesPushBody, ciOrgResourcesDiffBody, CI_APPLY_ENTITY_KINDS, CI_APPLY_OPERATIONS, ciApplyErrorBaseSchema, ciApplyErrorSchema, ciSyncCountSchema, ciSyncChangesSchema, ciSyncWarningSchema, ciSyncResponseSchema;
12113
- var init_chunk_DBQLPVOO = __esm({
12114
- "../../packages/core/dist/chunk-DBQLPVOO.js"() {
11946
+ var init_chunk_54QBGDXF = __esm({
11947
+ "../../packages/core/dist/chunk-54QBGDXF.js"() {
12115
11948
  "use strict";
12116
- init_chunk_D26NGKIY();
11949
+ init_chunk_GEYJNCIJ();
12117
11950
  init_chunk_7MRZJN4O();
12118
- init_chunk_6WCPZ26B();
11951
+ init_chunk_BQWVW6JO();
12119
11952
  init_chunk_LBDH7LCG();
12120
11953
  init_chunk_4LXDRTO4();
12121
11954
  init_chunk_T4Q5COKJ();
@@ -12551,7 +12384,7 @@ var init_chunk_6J742GLA = __esm({
12551
12384
  }
12552
12385
  });
12553
12386
 
12554
- // ../../packages/core/dist/chunk-JR2ITK6N.js
12387
+ // ../../packages/core/dist/chunk-3HSB6J4J.js
12555
12388
  function normalizeContactPhone(raw) {
12556
12389
  const compact = raw.trim().replace(/[\s\-.()]/g, "");
12557
12390
  const withPlus = compact.startsWith("00") ? `+${compact.slice(2)}` : compact;
@@ -12563,9 +12396,9 @@ function normalizeContactLabel(raw) {
12563
12396
  function importRowLabels(row, batchLabels) {
12564
12397
  return [.../* @__PURE__ */ new Set([...row.labels ?? [], ...batchLabels ?? []])];
12565
12398
  }
12566
- var CONTACT_ENVIRONMENTS, CONTACT_NAME_MAX, CONTACT_EMAIL_MAX, CONTACT_PHONE_INPUT_MAX, CONTACT_INSTAGRAM_SID_MAX, CONTACT_METADATA_MAX_BYTES, CONTACT_LABEL_MAX, CONTACT_LABELS_MAX, CONTACT_SCOPE_TAGS_MAX, CONTACT_PAGE_MAX, CONTACT_IMPORT_BATCH_MAX, CONTACT_SEARCH_MAX, CONTACT_LIST_NAME_MAX, CONTACT_LIST_NAME_REGEX, CONTACT_LIST_DESCRIPTION_MAX, CONTACT_LIST_FILTER_MAX, CONTACT_LIST_PINS_PER_REQUEST_MAX, SUPPRESSION_SCOPES, SUPPRESSION_ID_REGEX, contactName, contactPhone, contactEmail, contactInstagramSid, contactLabel, contactLabels, contactMetadata, scopeTagIds, contactVisibilitySchema, hasIdentity, IDENTITY_REQUIRED, contactBookOrgQuery, contactBookContactParam, contactBookListParam, contactBookHubParam, contactBookPageQuery, listContactBookContactsQuery, listHubContactBookContactsQuery, contactBookLinkCandidatesQuery, listContactBookListMembersQuery, contactRowFields, createContactBookContactBody, updateContactBookContactBody, contactImportRowSchema, importContactBookContactsBody, linkContactBookContactBody, listName, contactListFilterSchema, createContactBookListBody, updateContactBookListBody, updateContactBookListPinsBody, suppressionIdentitySchema, createContactBookSuppressionBody, contactBookSuppressionParam, listContactBookSuppressionsQuery, contactBookEmailUnsubscribeTokenSchema, contactBookEmailUnsubscribeQuery, orgListReferenceSchema;
12567
- var init_chunk_JR2ITK6N = __esm({
12568
- "../../packages/core/dist/chunk-JR2ITK6N.js"() {
12399
+ var CONTACT_ENVIRONMENTS, CONTACT_NAME_MAX, CONTACT_EMAIL_MAX, CONTACT_PHONE_INPUT_MAX, CONTACT_INSTAGRAM_SID_MAX, CONTACT_METADATA_MAX_BYTES, CONTACT_LABEL_MAX, CONTACT_LABELS_MAX, CONTACT_SCOPE_TAGS_MAX, CONTACT_PAGE_MAX, CONTACT_IMPORT_BATCH_MAX, CONTACT_SEARCH_MAX, CONTACT_LIST_NAME_MAX, CONTACT_LIST_NAME_REGEX, CONTACT_LIST_DESCRIPTION_MAX, CONTACT_LIST_FILTER_MAX, CONTACT_LIST_PINS_PER_REQUEST_MAX, SUPPRESSION_SCOPES, SUPPRESSION_ID_REGEX, contactName, contactPhone, contactEmail, contactInstagramSid, contactLabel, contactLabels, contactMetadata, scopeTagIds, contactVisibilitySchema, hasIdentity, IDENTITY_REQUIRED, contactBookOrgQuery, contactBookContactParam, contactBookListParam, contactBookHubParam, contactBookPageQuery, listContactBookContactsQuery, listHubContactBookContactsQuery, contactBookLinkCandidatesQuery, listContactBookListMembersQuery, contactRowFields, createContactBookContactBody, updateContactBookContactBody, contactImportRowSchema, importContactBookContactsBody, linkContactBookContactBody, CONTACT_CUSTOMER_BASE_ID_PATTERN, baseId, recordId, linkContactCustomerBody, unlinkContactCustomerQuery, listName, contactListFilterSchema, createContactBookListBody, updateContactBookListBody, updateContactBookListPinsBody, suppressionIdentitySchema, createContactBookSuppressionBody, contactBookSuppressionParam, listContactBookSuppressionsQuery, contactBookEmailUnsubscribeTokenSchema, contactBookEmailUnsubscribeQuery, orgListReferenceSchema;
12400
+ var init_chunk_3HSB6J4J = __esm({
12401
+ "../../packages/core/dist/chunk-3HSB6J4J.js"() {
12569
12402
  "use strict";
12570
12403
  init_zod();
12571
12404
  CONTACT_ENVIRONMENTS = ["production", "preview", "all"];
@@ -12684,6 +12517,16 @@ var init_chunk_JR2ITK6N = __esm({
12684
12517
  linkContactBookContactBody = external_exports.object({
12685
12518
  user_id: external_exports.string().min(1).max(128)
12686
12519
  }).strict();
12520
+ CONTACT_CUSTOMER_BASE_ID_PATTERN = /^[A-Za-z0-9_-]{1,128}$/;
12521
+ baseId = external_exports.string().regex(CONTACT_CUSTOMER_BASE_ID_PATTERN, { message: "Must be a base id" });
12522
+ recordId = external_exports.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_\-.:]{0,254}$/, { message: "Must be a record id" });
12523
+ linkContactCustomerBody = external_exports.object({
12524
+ base_id: baseId,
12525
+ record_id: recordId
12526
+ }).strict();
12527
+ unlinkContactCustomerQuery = contactBookOrgQuery.extend({
12528
+ base_id: baseId
12529
+ });
12687
12530
  listName = external_exports.string().trim().min(1).max(CONTACT_LIST_NAME_MAX).regex(CONTACT_LIST_NAME_REGEX, {
12688
12531
  message: 'Must be lowercase alphanumeric with hyphens (e.g. "vip-customers")'
12689
12532
  });
@@ -12726,14 +12569,14 @@ var init_chunk_JR2ITK6N = __esm({
12726
12569
  }
12727
12570
  });
12728
12571
 
12729
- // ../../packages/core/dist/chunk-EA2IJGKN.js
12572
+ // ../../packages/core/dist/chunk-XCDUP42J.js
12730
12573
  var COMMUNITIES_PER_ORG_MAX, COMMUNITY_NAME_MAX_LENGTH, COMMUNITY_REGISTRY_CLOSED_REASON, COMMUNITY_MEMBERS_MAX, COMMUNITY_ADMISSIONS, COMMUNITY_ACCESS_MAX, COMMUNITY_ACCESS_ADD_MAX, COMMUNITY_ACCESS_FULL_REASON, COMMUNITY_JOIN_SOURCE_MAX_LENGTH, COMMUNITY_JOIN_FLOW_TOKEN_MAX_LENGTH, COMMUNITY_ROOMS_MAX, COMMUNITY_ROOM_NAME_MAX_LENGTH, COMMUNITY_MESSAGE_MAX_LENGTH, COMMUNITY_MESSAGES_PAGE_SIZE, COMMUNITY_ATTACHMENT_URLS_MAX, COMMUNITY_POST_TITLE_MAX_LENGTH, COMMUNITY_POST_SEARCH_MAX_LENGTH, COMMUNITY_MEMBER_STATUSES, COMMUNITY_RULES_MAX_LENGTH, COMMUNITY_SLOW_MODE_MAX_SECONDS, COMMUNITY_COURSES_LABEL_MAX_LENGTH, COMMUNITY_LIVE_TICKET_PREFIX, COMMUNITY_STATS_DAYS, communityNameSchema, adminCreateCommunityBody, communityIdParam, communityJoinTokenSchema, communityJoinSourceSchema, communityJoinPreviewQuery, communityJoinBody, communityRoomKindSchema, communityRoomNameSchema, communityRoomIdParam, communityMessageIdParam, communityRoomCreateBody, communityRoomUpdateBody, communityMessagesQuery, communityMessageBodySchema, communityPostTitleSchema, communityAttachmentUploadSchema, communitySendBody, communityEditBody, communityPostIdParam, communityPostsQuery, communityAnswerBody, communityReadBody, communityAttachmentUrlsBody, communityPersonParam, communityOrgParam, communityPeopleQuery, communityCoursesLabelSchema, communityAdmissionSchema, communitySettingsBody, communityAccessEmailSchema, communityAccessAddBody, communityAccessQuery, communityAccessIdParam, communityBanBody, communityLockBody, communityPinBody, communityModLogQuery, communityReportsQuery, communityReportIdParam, communityLiveTicketSchema, communityLiveQuery, communityMuteBody, communityEmailUnsubscribeTokenSchema, communityEmailUnsubscribeQuery;
12731
- var init_chunk_EA2IJGKN = __esm({
12732
- "../../packages/core/dist/chunk-EA2IJGKN.js"() {
12574
+ var init_chunk_XCDUP42J = __esm({
12575
+ "../../packages/core/dist/chunk-XCDUP42J.js"() {
12733
12576
  "use strict";
12734
12577
  init_chunk_6J742GLA();
12735
12578
  init_chunk_ZVXO3XL6();
12736
- init_chunk_JR2ITK6N();
12579
+ init_chunk_3HSB6J4J();
12737
12580
  init_chunk_HZ6CADSY();
12738
12581
  init_zod();
12739
12582
  COMMUNITIES_PER_ORG_MAX = 10;
@@ -12834,7 +12677,7 @@ var init_chunk_EA2IJGKN = __esm({
12834
12677
  }
12835
12678
  });
12836
12679
 
12837
- // ../../packages/core/dist/chunk-QAWIPRNA.js
12680
+ // ../../packages/core/dist/chunk-3KYTITOR.js
12838
12681
  function parseCommunityLessonVideoUrl(url) {
12839
12682
  const parts = /^https?:\/\/([^/?#]+)([^?#]*)(?:\?([^#]*))?(?:#.*)?$/i.exec(url.trim());
12840
12683
  if (!parts) return null;
@@ -12860,10 +12703,10 @@ function communityLessonVideoWatchUrl(video) {
12860
12703
  }
12861
12704
  }
12862
12705
  var COMMUNITY_COURSES_MAX, COMMUNITY_COURSE_MODULES_MAX, COMMUNITY_COURSE_LESSONS_MAX, COMMUNITY_LESSONS_MAX, COMMUNITY_COURSE_TITLE_MAX_LENGTH, COMMUNITY_COURSE_DESCRIPTION_MAX_LENGTH, COMMUNITY_LESSON_BODY_MAX_LENGTH, COMMUNITY_LESSON_LINKS_MAX, COMMUNITY_LESSON_URL_MAX_LENGTH, YOUTUBE_ID, YOUTUBE_HOSTS, YOUTU_BE, YOUTUBE_ID_PATH, communityCourseIdParam, communityCourseModuleIdParam, communityLessonIdParam, communityCourseTitleSchema, communityCourseDescriptionSchema, communityCoursePositionSchema, communityLessonVideoUrlSchema, communityLessonLinkSchema, communityLessonLinksSchema, communityLessonBodySchema, communityCourseCreateBody, communityCourseUpdateBody, communityModuleCreateBody, communityModuleUpdateBody, communityLessonCreateBody, communityLessonUpdateBody;
12863
- var init_chunk_QAWIPRNA = __esm({
12864
- "../../packages/core/dist/chunk-QAWIPRNA.js"() {
12706
+ var init_chunk_3KYTITOR = __esm({
12707
+ "../../packages/core/dist/chunk-3KYTITOR.js"() {
12865
12708
  "use strict";
12866
- init_chunk_EA2IJGKN();
12709
+ init_chunk_XCDUP42J();
12867
12710
  init_chunk_HZ6CADSY();
12868
12711
  init_zod();
12869
12712
  COMMUNITY_COURSES_MAX = 20;
@@ -12945,29 +12788,58 @@ var init_chunk_YULHXJ5M = __esm({
12945
12788
  }
12946
12789
  });
12947
12790
 
12948
- // ../../packages/core/dist/chunk-UEJOG2Q7.js
12949
- var archiveHubIdParam, archiveConversationParams, archiveListQuery, archiveMessageObservabilityParams;
12950
- var init_chunk_UEJOG2Q7 = __esm({
12951
- "../../packages/core/dist/chunk-UEJOG2Q7.js"() {
12791
+ // ../../packages/core/dist/chunk-3O5XTDI2.js
12792
+ var CONSULT_THREAD_STATUSES, consultThreadStatus, CONSULT_THREAD_TITLE_MAX, consultThreadTitle, consultThreadSummary, listConsultThreadsQuery, listConsultThreadsResponse, createConsultThreadBody, createConsultThreadResponse, consultThreadIdParam, updateConsultThreadBody, updateConsultThreadResponse, CONSULT_AWAIT_TIMEOUT_MS;
12793
+ var init_chunk_3O5XTDI2 = __esm({
12794
+ "../../packages/core/dist/chunk-3O5XTDI2.js"() {
12952
12795
  "use strict";
12953
12796
  init_zod();
12954
- archiveHubIdParam = external_exports.object({
12955
- hubId: external_exports.string().uuid()
12797
+ CONSULT_THREAD_STATUSES = ["open", "awaiting", "resolved", "cancelled_at_close"];
12798
+ consultThreadStatus = external_exports.enum(CONSULT_THREAD_STATUSES);
12799
+ CONSULT_THREAD_TITLE_MAX = 120;
12800
+ consultThreadTitle = external_exports.string().trim().min(1).max(CONSULT_THREAD_TITLE_MAX);
12801
+ consultThreadSummary = external_exports.object({
12802
+ consult_thread_id: external_exports.string(),
12803
+ conversation_id: external_exports.string(),
12804
+ initiator_type: external_exports.enum(["team", "agent"]),
12805
+ initiator_id: external_exports.string(),
12806
+ engaged_agent_id: external_exports.string().nullable(),
12807
+ engaged_agent_name: external_exports.string().nullable(),
12808
+ title: external_exports.string().nullable(),
12809
+ status: consultThreadStatus,
12810
+ created_at: external_exports.string()
12956
12811
  });
12957
- archiveConversationParams = external_exports.object({
12958
- hubId: external_exports.string().uuid(),
12959
- conversationId: external_exports.string().uuid()
12812
+ listConsultThreadsQuery = external_exports.object({
12813
+ hub_id: external_exports.string().uuid()
12960
12814
  });
12961
- archiveListQuery = external_exports.object({
12962
- user_id: external_exports.string().optional(),
12963
- start: external_exports.string().optional(),
12964
- end: external_exports.string().optional(),
12965
- page: external_exports.string().regex(/^\d+$/).optional(),
12966
- page_size: external_exports.string().regex(/^\d+$/).optional()
12815
+ listConsultThreadsResponse = external_exports.object({
12816
+ threads: external_exports.array(consultThreadSummary)
12967
12817
  });
12968
- archiveMessageObservabilityParams = archiveConversationParams.extend({
12969
- messageId: external_exports.string().uuid()
12818
+ createConsultThreadBody = external_exports.object({
12819
+ hub_id: external_exports.string().uuid(),
12820
+ title: consultThreadTitle.optional(),
12821
+ // Optionally engage a consultant on creation. Validated server-side against the
12822
+ // hub's `consultant`-role agents; a non-consultant / unknown id is rejected.
12823
+ engaged_agent_id: external_exports.string().uuid().optional()
12824
+ });
12825
+ createConsultThreadResponse = external_exports.object({
12826
+ thread: consultThreadSummary
12827
+ });
12828
+ consultThreadIdParam = external_exports.object({
12829
+ id: external_exports.string().uuid(),
12830
+ threadId: external_exports.string().uuid()
12831
+ });
12832
+ updateConsultThreadBody = external_exports.object({
12833
+ hub_id: external_exports.string().uuid(),
12834
+ title: consultThreadTitle.optional(),
12835
+ engaged_agent_id: external_exports.string().uuid().optional()
12836
+ }).refine((v) => v.title !== void 0 || v.engaged_agent_id !== void 0, {
12837
+ message: "Provide a title and/or an engaged_agent_id to update"
12970
12838
  });
12839
+ updateConsultThreadResponse = external_exports.object({
12840
+ thread: consultThreadSummary
12841
+ });
12842
+ CONSULT_AWAIT_TIMEOUT_MS = 15 * 6e4;
12971
12843
  }
12972
12844
  });
12973
12845
 
@@ -13050,15 +12922,15 @@ var init_chunk_ZHJEQBXJ = __esm({
13050
12922
  }
13051
12923
  });
13052
12924
 
13053
- // ../../packages/core/dist/chunk-WNWIYFR3.js
12925
+ // ../../packages/core/dist/chunk-LQY2OCQL.js
13054
12926
  function filterNamesAnything(filter) {
13055
12927
  return filter.labels.length + filter.scope_tag_ids.length > 0;
13056
12928
  }
13057
12929
  var hubListNameSchema, HUB_LIST_FILTER_REQUIRED, hubContactListFilterSchema, hubContactListIdParam, hubContactListHubQuery, description, createHubContactListBody, updateHubContactListBody;
13058
- var init_chunk_WNWIYFR3 = __esm({
13059
- "../../packages/core/dist/chunk-WNWIYFR3.js"() {
12930
+ var init_chunk_LQY2OCQL = __esm({
12931
+ "../../packages/core/dist/chunk-LQY2OCQL.js"() {
13060
12932
  "use strict";
13061
- init_chunk_JR2ITK6N();
12933
+ init_chunk_3HSB6J4J();
13062
12934
  init_zod();
13063
12935
  hubListNameSchema = orgListReferenceSchema;
13064
12936
  HUB_LIST_FILTER_REQUIRED = "A hub list names at least one label or scope tag";
@@ -13100,14 +12972,14 @@ var init_chunk_F3JHI4Y4 = __esm({
13100
12972
  }
13101
12973
  });
13102
12974
 
13103
- // ../../packages/core/dist/chunk-ALUW3KZS.js
12975
+ // ../../packages/core/dist/chunk-MTQ6G7VB.js
13104
12976
  var AUTOMATION_TRIGGER_TYPES, AUTOMATION_EVENT_TYPES, AUTOMATION_TARGET_TYPES, AUTOMATION_ACTION_TYPES, AUTOMATION_CHANNEL_TYPES, AUTOMATION_PURPOSES, AUTOMATION_NAME_MAX, AUTOMATION_DESCRIPTION_MAX, AUTOMATION_INSTRUCTIONS_MAX, AUTOMATION_TEXT_MAX, AUTOMATION_CRON_MAX, AUTOMATION_WEBHOOK_AUTHS, AUTOMATION_WEBHOOK_HEADERS, AUTOMATION_WEBHOOK_BODY_MAX_BYTES, AUTOMATION_WEBHOOK_HEADER_NAME_MAX, WEBHOOK_RESERVED_HEADERS, automationTriggerSchema, automationTargetSchema, automationActionSchema, automationGateSchema, automationName, automationDescription, automationIdParam, automationHubQuery, automationWebhookParams, AUTOMATION_RUNS_PAGE_MAX, listAutomationRunsQuery, createAutomationBody, updateAutomationBody, AUTOMATION_ALERT_CATEGORIES, AUTOMATION_BLOCKED_ALERT_CATEGORY, automationEventSubscriberParam;
13105
- var init_chunk_ALUW3KZS = __esm({
13106
- "../../packages/core/dist/chunk-ALUW3KZS.js"() {
12977
+ var init_chunk_MTQ6G7VB = __esm({
12978
+ "../../packages/core/dist/chunk-MTQ6G7VB.js"() {
13107
12979
  "use strict";
13108
- init_chunk_WNWIYFR3();
13109
- init_chunk_6WCPZ26B();
13110
- init_chunk_JR2ITK6N();
12980
+ init_chunk_LQY2OCQL();
12981
+ init_chunk_BQWVW6JO();
12982
+ init_chunk_3HSB6J4J();
13111
12983
  init_chunk_F3JHI4Y4();
13112
12984
  init_chunk_DHPUPI4Y();
13113
12985
  init_chunk_T7KQKDET();
@@ -13357,6 +13229,118 @@ var init_chunk_ZJJ5ODOD = __esm({
13357
13229
  }
13358
13230
  });
13359
13231
 
13232
+ // ../../packages/core/dist/chunk-7CYHPF35.js
13233
+ var appMessageSenderType, appMessageReceiverType, apiChannelMessage, apiChannelMessageBody, appMessageBody, appMessageResponse;
13234
+ var init_chunk_7CYHPF35 = __esm({
13235
+ "../../packages/core/dist/chunk-7CYHPF35.js"() {
13236
+ "use strict";
13237
+ init_chunk_HZ6CADSY();
13238
+ init_zod();
13239
+ appMessageSenderType = external_exports.enum(["user", "team"]);
13240
+ appMessageReceiverType = external_exports.enum(["user", "team", "agent", "assistant"]).transform((v) => v === "assistant" ? "agent" : v);
13241
+ apiChannelMessage = external_exports.object({
13242
+ text: clientOptionalString,
13243
+ attachments: external_exports.array(messageAttachment).max(MAX_ATTACHMENTS_PER_MESSAGE).nullish().transform((v) => v ?? void 0)
13244
+ }).refine((m) => m.text && m.text.length > 0 || m.attachments && m.attachments.length > 0, {
13245
+ message: "message must have text or at least one attachment"
13246
+ });
13247
+ apiChannelMessageBody = external_exports.object({
13248
+ // Correlation id (task hubs): new → new conversation, repeat → continue. min 1 so an
13249
+ // empty string can't masquerade as a ref. Mutually exclusive with conversation_id.
13250
+ external_ref: external_exports.string().min(1).max(256).optional(),
13251
+ // Continue a specific WayAI conversation (authorized against the hub/channel + owner).
13252
+ // UUID-validated here (unlike the app channel, whose client we control): allocation
13253
+ // only treats a UUID-shaped id as a provided conversation, so a malformed id would
13254
+ // otherwise skip the owner guard and silently MINT a new conversation instead of
13255
+ // rejecting. A format 400 is shape-only — not an existence oracle (a valid-but-unknown
13256
+ // UUID still collapses to the opaque authorization error downstream).
13257
+ conversation_id: external_exports.string().uuid().optional(),
13258
+ // On-behalf-of end-user identity. Absent → per-connection service principal (task-hub
13259
+ // only; chat hub rejects with 422 in the route).
13260
+ user: external_exports.object({
13261
+ id: external_exports.string().min(1),
13262
+ email: clientOptionalString,
13263
+ name: clientOptionalString
13264
+ }).optional(),
13265
+ message: apiChannelMessage,
13266
+ // Idempotency key: maps to channel_message_sid, deduped within one conversation
13267
+ // (ConversationDO.storeMessage). A retried POST resolves to the same conversation (a chat
13268
+ // hub's user, the external_ref, the conversation_id, or on a task hub with neither, this key
13269
+ // scoped by the sender), so it echoes the original message_id and skips billing / turn
13270
+ // dispatch. A failed store answers a retryable 503 only when this key is set; without it a
13271
+ // retry could store the message twice, so it answers 400.
13272
+ client_message_id: external_exports.string().min(1).max(256).optional()
13273
+ }).refine((b) => !(b.external_ref && b.conversation_id), {
13274
+ message: "provide external_ref or conversation_id, not both",
13275
+ path: ["external_ref"]
13276
+ });
13277
+ appMessageBody = external_exports.object({
13278
+ // Message content — three historical aliases. All optional: an attachment-only
13279
+ // or voice-only message carries no text.
13280
+ content: clientOptionalString,
13281
+ message_text: clientOptionalString,
13282
+ message_body: clientOptionalString,
13283
+ // Conversation context. Ids are plain strings rather than `.uuid()` on purpose:
13284
+ // they are AUTHORIZED downstream, which is the stronger guarantee — a well-formed
13285
+ // uuid belonging to another tenant must fail just as hard as junk. `hub_id` is
13286
+ // gated by `assertHubEndUserAccess` (gh #3286) and `conversation_id` by HubDO's
13287
+ // conversation_index owner check (gh #2781, #3281). The route's own falsy guards
13288
+ // ('hub_id is required') still reject an empty one.
13289
+ hub_id: clientOptionalString,
13290
+ channel_id: clientOptionalString,
13291
+ conversation_id: clientOptionalString,
13292
+ hub_type: external_exports.enum(["chat", "task"]).nullish().transform((v) => v ?? void 0),
13293
+ // Stable idempotency key for one explicit task-hub launcher. HubDO scopes it
13294
+ // to the authenticated user and resolves retries/tabs to one conversation.
13295
+ task_start_id: external_exports.string().uuid().nullish().transform((v) => v ?? void 0),
13296
+ // Routing.
13297
+ sender_type: appMessageSenderType.nullish().transform((v) => v ?? void 0),
13298
+ receiver_type: appMessageReceiverType.nullish().transform((v) => v ?? void 0),
13299
+ // Only meaningful on a team send, where `validateAppTeamSendContext` proves the
13300
+ // caller may send to this receiver. Absent on a team send to a conversation with no
13301
+ // person, which names its `conversation_id` instead. The end-user branch ignores it —
13302
+ // see the receiver derivation in the route.
13303
+ user_receiver_id: clientOptionalString,
13304
+ // ── Internal consult (consultant-agents PR 2 — H1.0) ──────────────────────
13305
+ // A team member handling a customer conversation can tag a `consultant`-role
13306
+ // agent for a PRIVATE, team-only exchange that never reaches the customer. A
13307
+ // consult send is a team send with `receiver_type: 'agent'` targeting the
13308
+ // consultant; `user_receiver_id` identifies the customer whose conversation this is
13309
+ // (and is authorized by `validateAppTeamSendContext`, exactly as a team→user send is),
13310
+ // and is absent, as on a team→user send, when the conversation has no person. The consultant is resolved from `agent_receiver_id`
13311
+ // when supplied, else from an `@mention` parsed out of the message text against
13312
+ // the hub's consultant agents. `consult_thread_id` continues an existing thread;
13313
+ // absent, the route creates/reuses the single implicit thread. These fields are
13314
+ // inert on every non-consult send (end-user send, team→user send).
13315
+ agent_receiver_id: clientOptionalString,
13316
+ consult_thread_id: clientOptionalString,
13317
+ is_first_message: clientOptionalBoolean,
13318
+ end_conversation: clientOptionalBoolean,
13319
+ // Pre-generated by the client so the optimistic bubble and the stored row share
13320
+ // a key (transcription live-updates land on the same row instead of duplicating).
13321
+ message_id: clientOptionalString,
13322
+ attachments: external_exports.array(messageAttachment).max(MAX_ATTACHMENTS_PER_MESSAGE).nullish().transform((v) => v ?? void 0),
13323
+ // Base64-encoded audio for STT. Size-capped in the route (the cap is a byte
13324
+ // budget tied to the /channels/* bodyLimit, not a shape rule).
13325
+ audio_file: clientOptionalString
13326
+ });
13327
+ appMessageResponse = external_exports.object({
13328
+ success: external_exports.boolean(),
13329
+ message: external_exports.string(),
13330
+ result: external_exports.object({
13331
+ conversation_id: external_exports.string().optional(),
13332
+ message_id: external_exports.string().optional(),
13333
+ status: external_exports.string().optional(),
13334
+ files: external_exports.array(external_exports.record(external_exports.string(), external_exports.unknown())).optional(),
13335
+ // True when this request reused a task-start/message id already accepted by
13336
+ // the server. Clients must replace their optimistic payload with a fresh
13337
+ // authoritative read because another tab may have won with different text.
13338
+ deduped: external_exports.boolean().optional()
13339
+ }).optional()
13340
+ });
13341
+ }
13342
+ });
13343
+
13360
13344
  // ../../packages/core/dist/chunk-NVKU5PPQ.js
13361
13345
  var ADMIN_SKILL_NAME_REGEX, adminSkillNameParam;
13362
13346
  var init_chunk_NVKU5PPQ = __esm({
@@ -13999,6 +13983,32 @@ var init_chunk_2PZIF56U = __esm({
13999
13983
  }
14000
13984
  });
14001
13985
 
13986
+ // ../../packages/core/dist/chunk-UEJOG2Q7.js
13987
+ var archiveHubIdParam, archiveConversationParams, archiveListQuery, archiveMessageObservabilityParams;
13988
+ var init_chunk_UEJOG2Q7 = __esm({
13989
+ "../../packages/core/dist/chunk-UEJOG2Q7.js"() {
13990
+ "use strict";
13991
+ init_zod();
13992
+ archiveHubIdParam = external_exports.object({
13993
+ hubId: external_exports.string().uuid()
13994
+ });
13995
+ archiveConversationParams = external_exports.object({
13996
+ hubId: external_exports.string().uuid(),
13997
+ conversationId: external_exports.string().uuid()
13998
+ });
13999
+ archiveListQuery = external_exports.object({
14000
+ user_id: external_exports.string().optional(),
14001
+ start: external_exports.string().optional(),
14002
+ end: external_exports.string().optional(),
14003
+ page: external_exports.string().regex(/^\d+$/).optional(),
14004
+ page_size: external_exports.string().regex(/^\d+$/).optional()
14005
+ });
14006
+ archiveMessageObservabilityParams = archiveConversationParams.extend({
14007
+ messageId: external_exports.string().uuid()
14008
+ });
14009
+ }
14010
+ });
14011
+
14002
14012
  // ../../packages/core/dist/chunk-SOJMWM63.js
14003
14013
  var init_chunk_SOJMWM63 = __esm({
14004
14014
  "../../packages/core/dist/chunk-SOJMWM63.js"() {
@@ -14221,57 +14231,56 @@ var init_contracts = __esm({
14221
14231
  init_chunk_SXDX4GHS();
14222
14232
  init_chunk_FK6HBXM7();
14223
14233
  init_chunk_VXEAR36B();
14224
- init_chunk_GPM7PE44();
14225
14234
  init_chunk_DGKMMFIR();
14226
14235
  init_chunk_ZC6YGHNX();
14227
14236
  init_chunk_ACKF2MVU();
14228
- init_chunk_ZXK6N2HN();
14229
14237
  init_chunk_Y7CFCYX4();
14230
14238
  init_chunk_5DGHIY7L();
14231
14239
  init_chunk_BVQE66I2();
14232
14240
  init_chunk_BEOHBREG();
14233
14241
  init_chunk_IPDOHAZ5();
14234
- init_chunk_SY6PLCPK();
14242
+ init_chunk_GPM7PE44();
14235
14243
  init_chunk_YUZFHVB2();
14236
14244
  init_chunk_34LE6P7E();
14237
14245
  init_chunk_FPSDNS2E();
14238
- init_chunk_LKBSHANA();
14246
+ init_chunk_ZXK6N2HN();
14239
14247
  init_chunk_VOC3AGY4();
14240
14248
  init_chunk_C4HEZ7ZI();
14241
14249
  init_chunk_IR2NOSI3();
14242
14250
  init_chunk_EA23LSDS();
14243
- init_chunk_3O5XTDI2();
14251
+ init_chunk_SY6PLCPK();
14244
14252
  init_chunk_LWMLR2WI();
14245
14253
  init_chunk_ACGAI25T();
14246
14254
  init_chunk_MH4O3YEX();
14247
- init_chunk_YVHDDEQV();
14255
+ init_chunk_SPE6FAYO();
14248
14256
  init_chunk_KSTYTQ7I();
14249
- init_chunk_7CYHPF35();
14257
+ init_chunk_LKBSHANA();
14250
14258
  init_chunk_BPCNB5RT();
14251
- init_chunk_DBQLPVOO();
14252
- init_chunk_D26NGKIY();
14259
+ init_chunk_54QBGDXF();
14260
+ init_chunk_GEYJNCIJ();
14253
14261
  init_chunk_7MRZJN4O();
14254
14262
  init_chunk_JDJ4EUOL();
14255
- init_chunk_QAWIPRNA();
14256
- init_chunk_EA2IJGKN();
14263
+ init_chunk_3KYTITOR();
14264
+ init_chunk_XCDUP42J();
14257
14265
  init_chunk_6J742GLA();
14258
14266
  init_chunk_ZVXO3XL6();
14259
14267
  init_chunk_YULHXJ5M();
14260
- init_chunk_UEJOG2Q7();
14268
+ init_chunk_3O5XTDI2();
14261
14269
  init_chunk_ZHJEQBXJ();
14262
- init_chunk_ALUW3KZS();
14263
- init_chunk_WNWIYFR3();
14264
- init_chunk_6WCPZ26B();
14265
- init_chunk_JR2ITK6N();
14270
+ init_chunk_MTQ6G7VB();
14271
+ init_chunk_LQY2OCQL();
14272
+ init_chunk_BQWVW6JO();
14273
+ init_chunk_3HSB6J4J();
14266
14274
  init_chunk_IG6QBZMA();
14267
14275
  init_chunk_ZJJ5ODOD();
14268
14276
  init_chunk_PZPOUXJR();
14269
14277
  init_chunk_LBDH7LCG();
14270
14278
  init_chunk_4LXDRTO4();
14271
14279
  init_chunk_E4DIIOOE();
14280
+ init_chunk_7CYHPF35();
14272
14281
  init_chunk_FMXFEZN4();
14273
- init_chunk_5KFFZX2J();
14274
- init_chunk_VBUWGVFY();
14282
+ init_chunk_LM3FU67F();
14283
+ init_chunk_QCQUZL4L();
14275
14284
  init_chunk_NVKU5PPQ();
14276
14285
  init_chunk_2FCLSQSQ();
14277
14286
  init_chunk_FECLIZTY();
@@ -14283,6 +14292,7 @@ var init_contracts = __esm({
14283
14292
  init_chunk_ACN6GXU6();
14284
14293
  init_chunk_OMPT4ZHR();
14285
14294
  init_chunk_2PZIF56U();
14295
+ init_chunk_UEJOG2Q7();
14286
14296
  init_chunk_SOJMWM63();
14287
14297
  init_chunk_WEXVYJ5H();
14288
14298
  init_chunk_LZDVDC2S();
@@ -14474,6 +14484,19 @@ var init_api_client = __esm({
14474
14484
  }
14475
14485
  // The org-admin community routes (gh #5003, `wayai communities`): an owner or admin of the
14476
14486
  // community's org, on an interactive session only — a scoped token is refused with 403.
14487
+ /**
14488
+ * Link a contact to its customer record, a root record of one of the org's bases (#5083 RK2 A3).
14489
+ * A browser sign-in only: the route refuses an API token.
14490
+ */
14491
+ async linkContactCustomer(orgId, contactId, body) {
14492
+ const qs = new URLSearchParams({ organization_id: orgId });
14493
+ return this.request("PUT", `/api/contact-book/contacts/${encodeURIComponent(contactId)}/customer?${qs}`, body);
14494
+ }
14495
+ /** Unlink a contact from its customer record in one base (owner decision 142). A browser sign-in only. */
14496
+ async unlinkContactCustomer(orgId, contactId, baseId2) {
14497
+ const qs = new URLSearchParams({ organization_id: orgId, base_id: baseId2 });
14498
+ return this.request("DELETE", `/api/contact-book/contacts/${encodeURIComponent(contactId)}/customer?${qs}`);
14499
+ }
14477
14500
  async listOrgCommunities(orgId) {
14478
14501
  return this.request("GET", `/api/communities/orgs/${encodeURIComponent(orgId)}`);
14479
14502
  }
@@ -17307,6 +17330,7 @@ var init_utils = __esm({
17307
17330
  "conversations",
17308
17331
  "alerts",
17309
17332
  "communities",
17333
+ "contacts",
17310
17334
  "knowledge"
17311
17335
  ]);
17312
17336
  HELP_AND_VERSION = ["help", "--help", "-h", "--version", "-v"];
@@ -17314,6 +17338,7 @@ var init_utils = __esm({
17314
17338
  ["pull", "all"],
17315
17339
  ["push", "all"],
17316
17340
  ["communities", "all"],
17341
+ ["contacts", "all"],
17317
17342
  ["knowledge", "all"],
17318
17343
  ["use", "selectors"],
17319
17344
  ["unbind", "selectors"],
@@ -21665,12 +21690,12 @@ function writeBaseFolder(folder, meta, config) {
21665
21690
  }
21666
21691
  return delta;
21667
21692
  }
21668
- function markProductionMirror(folder, baseId) {
21693
+ function markProductionMirror(folder, baseId2) {
21669
21694
  const file = path21.join(folder, BASE_META_FILE);
21670
21695
  try {
21671
21696
  const body = readFileNoFollow(folder, file)?.toString("utf-8");
21672
21697
  if (body === void 0 || body.startsWith(MIRROR_MARKER_PREFIX)) return;
21673
- const banner = `${MIRROR_MARKER_PREFIX} "${baseId}". Edits are ignored; \`wayai push\` refuses it. Edit the linked preview instead.
21698
+ const banner = `${MIRROR_MARKER_PREFIX} "${baseId2}". Edits are ignored; \`wayai push\` refuses it. Edit the linked preview instead.
21674
21699
  `;
21675
21700
  writeFileNoFollow(folder, file, Buffer.from(banner + body, "utf-8"));
21676
21701
  } catch {
@@ -21796,10 +21821,10 @@ function createPreview(client, originId, opts) {
21796
21821
  ...opts.analytics ? { analytics: opts.analytics } : {}
21797
21822
  });
21798
21823
  }
21799
- function deleteEntity(client, baseId, kind, id) {
21824
+ function deleteEntity(client, baseId2, kind, id) {
21800
21825
  return client.request(
21801
21826
  "DELETE",
21802
- `/v1/${pathSegment(baseId, "base id")}/${ENTITY_DIRS[kind]}/${pathSegment(id, `${kind} id`)}`
21827
+ `/v1/${pathSegment(baseId2, "base id")}/${ENTITY_DIRS[kind]}/${pathSegment(id, `${kind} id`)}`
21803
21828
  );
21804
21829
  }
21805
21830
  var init_api = __esm({
@@ -21998,40 +22023,40 @@ async function pullBase(gitRootOrNull, selector, args2) {
21998
22023
  const gitRoot = requireGitRoot(gitRootOrNull);
21999
22024
  const target = resolveBaseTarget(gitRoot, selector);
22000
22025
  const basesDir = resolveBasesDir(gitRoot);
22001
- const baseId = targetBaseId(target, selector);
22002
- if (!baseId) {
22026
+ const baseId2 = targetBaseId(target, selector);
22027
+ if (!baseId2) {
22003
22028
  throw expected(
22004
22029
  `Could not determine the base id for ${target.folder}. Pass the base id explicitly.`
22005
22030
  );
22006
22031
  }
22007
22032
  const client = await createDataClient();
22008
22033
  console.log("Fetching base configuration...");
22009
- const record = await getBaseRecord(client, baseId);
22034
+ const record = await getBaseRecord(client, baseId2);
22010
22035
  if (record.environment === "production") {
22011
- const folder = await writeProductionMirror(client, basesDir, record.id ?? baseId, record);
22036
+ const folder = await writeProductionMirror(client, basesDir, record.id ?? baseId2, record);
22012
22037
  console.log(`Production base mirrored (read-only) \u2192 ${folder}`);
22013
22038
  return;
22014
22039
  }
22015
- assertInScope("bases", baseId);
22040
+ assertInScope("bases", baseId2);
22016
22041
  if (target.exists && !autoConfirm) {
22017
22042
  const ok = await confirm(
22018
- `Overwrite local files in ${path23.relative(gitRoot, target.folder)} with the server config for "${sanitizeTerminalText(baseId)}"?`
22043
+ `Overwrite local files in ${path23.relative(gitRoot, target.folder)} with the server config for "${sanitizeTerminalText(baseId2)}"?`
22019
22044
  );
22020
22045
  if (!ok) {
22021
22046
  console.log("Cancelled.");
22022
22047
  return;
22023
22048
  }
22024
22049
  }
22025
- const config = await getConfig(client, baseId);
22050
+ const config = await getConfig(client, baseId2);
22026
22051
  const isFirstPull = !target.exists;
22027
- const delta = writeBaseFolder(target.folder, metaFromRecord(record, baseId), config);
22052
+ const delta = writeBaseFolder(target.folder, metaFromRecord(record, baseId2), config);
22028
22053
  console.log(`Base configuration written to ${target.folder}`);
22029
22054
  console.log(
22030
22055
  ` ${ENTITY_KINDS.map((kind) => `${(config[kind] ?? []).length} ${kind}`).join(", ")}`
22031
22056
  );
22032
22057
  if (!isFirstPull) printLocalFileChanges(delta);
22033
22058
  console.log(" Credential values are not written. Manage them with `wayai bases credentials`.");
22034
- seedScopeIfEmpty("bases", baseId);
22059
+ seedScopeIfEmpty("bases", baseId2);
22035
22060
  if (record.origin_base_id) {
22036
22061
  await mirrorLinkedProduction(client, basesDir, record.origin_base_id);
22037
22062
  }
@@ -22101,25 +22126,25 @@ async function pushBase(gitRootOrNull, selector, args2) {
22101
22126
  return;
22102
22127
  }
22103
22128
  const client = await createDataClient();
22104
- let baseId = meta.base_id;
22105
- if (!baseId) {
22129
+ let baseId2 = meta.base_id;
22130
+ if (!baseId2) {
22106
22131
  const created = await createDeclaredPreview(client, target, parsed, autoConfirm);
22107
22132
  if (!created) return;
22108
- baseId = created;
22133
+ baseId2 = created;
22109
22134
  } else {
22110
- const record = await getBaseRecord(client, baseId);
22135
+ const record = await getBaseRecord(client, baseId2);
22111
22136
  if (record.environment && record.environment !== "preview") {
22112
22137
  throw expected(
22113
- `"${sanitizeTerminalText(baseId)}" is a ${sanitizeTerminalText(record.environment)} base. Push operates on previews \u2014 promote with \`wayai bases promote\`.`
22138
+ `"${sanitizeTerminalText(baseId2)}" is a ${sanitizeTerminalText(record.environment)} base. Push operates on previews \u2014 promote with \`wayai bases promote\`.`
22114
22139
  );
22115
22140
  }
22116
- assertInScope("bases", baseId);
22141
+ assertInScope("bases", baseId2);
22117
22142
  }
22118
- const diff = await diffConfig(client, baseId, config);
22143
+ const diff = await diffConfig(client, baseId2, config);
22119
22144
  printLintWarnings(diff.warnings);
22120
22145
  if (isDiffEmpty(diff)) {
22121
- console.log(`No changes \u2014 preview "${sanitizeTerminalText(baseId)}" already matches your files.`);
22122
- if (!dryRun) seedScopeIfEmpty("bases", baseId);
22146
+ console.log(`No changes \u2014 preview "${sanitizeTerminalText(baseId2)}" already matches your files.`);
22147
+ if (!dryRun) seedScopeIfEmpty("bases", baseId2);
22123
22148
  return;
22124
22149
  }
22125
22150
  console.log(renderDiff(diff));
@@ -22129,13 +22154,13 @@ async function pushBase(gitRootOrNull, selector, args2) {
22129
22154
  }
22130
22155
  if (!autoConfirm) {
22131
22156
  const ok = await confirm(`
22132
- Apply these changes to preview "${sanitizeTerminalText(baseId)}"?`);
22157
+ Apply these changes to preview "${sanitizeTerminalText(baseId2)}"?`);
22133
22158
  if (!ok) {
22134
22159
  console.log("Cancelled.");
22135
22160
  return;
22136
22161
  }
22137
22162
  }
22138
- const result = await applyConfig(client, baseId, config);
22163
+ const result = await applyConfig(client, baseId2, config);
22139
22164
  const secretGroups = [
22140
22165
  ["trigger", result.new_trigger_secrets],
22141
22166
  ["inbound webhook", result.new_inbound_webhook_secrets]
@@ -22162,7 +22187,7 @@ ${RED}${removals.length} ${word} not in your files were left on the base. Re-run
22162
22187
  Delete ${removals.length} server ${word} not in your files? Record types cascade to their records.`
22163
22188
  )) {
22164
22189
  for (const removal of removals) {
22165
- await deleteEntity(client, baseId, removal.kind, removal.id);
22190
+ await deleteEntity(client, baseId2, removal.kind, removal.id);
22166
22191
  console.log(` - deleted ${removal.kind} ${sanitizeTerminalText(removal.id)}`);
22167
22192
  }
22168
22193
  } else {
@@ -22170,8 +22195,8 @@ Delete ${removals.length} server ${word} not in your files? Record types cascade
22170
22195
  }
22171
22196
  }
22172
22197
  console.log(`
22173
- Pushed to preview "${sanitizeTerminalText(baseId)}".`);
22174
- seedScopeIfEmpty("bases", baseId);
22198
+ Pushed to preview "${sanitizeTerminalText(baseId2)}".`);
22199
+ seedScopeIfEmpty("bases", baseId2);
22175
22200
  }
22176
22201
  var init_sync = __esm({
22177
22202
  "src/data/config-as-code/sync.ts"() {
@@ -27572,9 +27597,9 @@ async function conversationsCommand(args2) {
27572
27597
  if (result.partial || result.hubs_queried === 0) process.exit(1);
27573
27598
  return;
27574
27599
  }
27575
- for (const failure of result.errors) {
27576
- const where = failure.scope_kind === "hub" ? `hub ${sanitizeTerminalText(failure.hub_name || failure.hub_id || "")} (${failure.hub_id})` : `organization ${failure.organization_id}`;
27577
- console.error(`Could not read ${where}: ${sanitizeTerminalText(failure.error)}`);
27600
+ for (const failure2 of result.errors) {
27601
+ const where = failure2.scope_kind === "hub" ? `hub ${sanitizeTerminalText(failure2.hub_name || failure2.hub_id || "")} (${failure2.hub_id})` : `organization ${failure2.organization_id}`;
27602
+ console.error(`Could not read ${where}: ${sanitizeTerminalText(failure2.error)}`);
27578
27603
  }
27579
27604
  if (result.hubs_queried === 0) {
27580
27605
  console.error(
@@ -33071,6 +33096,122 @@ These commands need a browser sign-in (\`wayai login\`). An API token
33071
33096
  }
33072
33097
  });
33073
33098
 
33099
+ // src/commands/contacts.ts
33100
+ var contacts_exports = {};
33101
+ __export(contacts_exports, {
33102
+ contactsCommand: () => contactsCommand
33103
+ });
33104
+ import { parseArgs as parseArgs22 } from "util";
33105
+ function usageError2(message) {
33106
+ return expected(`${message}
33107
+
33108
+ ${USAGE3}`);
33109
+ }
33110
+ function parse2(args2) {
33111
+ try {
33112
+ return parseArgs22({
33113
+ args: args2,
33114
+ options: {
33115
+ org: { type: "string" },
33116
+ base: { type: "string" },
33117
+ record: { type: "string" },
33118
+ json: { type: "boolean" }
33119
+ },
33120
+ allowPositionals: true,
33121
+ strict: true
33122
+ });
33123
+ } catch (err) {
33124
+ throw usageError2(err instanceof Error ? err.message : String(err));
33125
+ }
33126
+ }
33127
+ function resolveOrgId2(flag) {
33128
+ if (flag !== void 0) {
33129
+ if (!UUID_RE3.test(flag)) throw expected(`Invalid --org ${JSON.stringify(flag)}: expected an organization id (a UUID).`);
33130
+ return flag;
33131
+ }
33132
+ const bound = readRepoConfigUnlessBlocked()?.organization_id;
33133
+ if (bound) return bound;
33134
+ throw expected("No organization: pass --org <org_id>, or run this inside a workspace scoped with `wayai init`.");
33135
+ }
33136
+ function failure(err, accessToken) {
33137
+ if (!(err instanceof ApiError)) return err;
33138
+ if (err.status === 403 && identifyTokenType(accessToken) === "way_token") {
33139
+ const override2 = envTokenOverride() ? " WAYAI_TOKEN is set in this shell and is sent instead of your sign-in: unset it first." : "";
33140
+ return expected(
33141
+ `A contact's customer record is linked from a browser sign-in only, and this login is an API token. Run \`wayai login\` (without --token).${override2}`
33142
+ );
33143
+ }
33144
+ if (err.status >= 400 && err.status < 500) return expected(sanitizeTerminalText(extractApiMessage(err)));
33145
+ return err;
33146
+ }
33147
+ async function contactsCommand(args2) {
33148
+ if (wantsHelp(args2) || args2.length === 0) {
33149
+ console.log(USAGE3);
33150
+ return;
33151
+ }
33152
+ const { values, positionals } = parse2(args2);
33153
+ const [sub, contactId, ...extra] = positionals;
33154
+ if (!SUBCOMMANDS2.includes(sub)) throw usageError2(`Unknown subcommand ${JSON.stringify(sub)}.`);
33155
+ if (contactId === void 0 || extra.length > 0) throw usageError2(`${sub} takes one <contact_id>.`);
33156
+ if (!UUID_RE3.test(contactId)) throw usageError2(`Invalid <contact_id> ${JSON.stringify(contactId)}: expected a contact id (a UUID).`);
33157
+ if (!values.base) throw usageError2(`${sub} needs --base <base_id>.`);
33158
+ if (!isValidBaseId(values.base)) throw usageError2(`Invalid --base ${JSON.stringify(values.base)}: a base id is ${BASE_ID_RULE}.`);
33159
+ if (sub === "link-customer" && !values.record) throw usageError2("link-customer needs --record <record_id>.");
33160
+ if (sub === "unlink-customer" && values.record !== void 0) throw usageError2("--record applies only to link-customer.");
33161
+ const orgId = resolveOrgId2(values.org);
33162
+ const { config, accessToken } = await requireAuth();
33163
+ const api = new ApiClient({ apiUrl: config.api_url, accessToken, onUnauthorized: () => getAccessToken(config) });
33164
+ let customer;
33165
+ try {
33166
+ ({ customer } = sub === "link-customer" ? await api.linkContactCustomer(orgId, contactId, { base_id: values.base, record_id: values.record }) : await api.unlinkContactCustomer(orgId, contactId, values.base));
33167
+ } catch (err) {
33168
+ throw failure(err, accessToken);
33169
+ }
33170
+ if (values.json) {
33171
+ console.log(JSON.stringify(customer, null, 2));
33172
+ return;
33173
+ }
33174
+ const where = `base ${sanitizeTerminalText(customer.base_id)} (${sanitizeTerminalText(customer.record_type)})`;
33175
+ console.log(sub === "link-customer" ? `Contact ${customer.contact_id} is linked to customer record ${sanitizeTerminalText(customer.record_id)} in ${where}.` : `Contact ${customer.contact_id} is unlinked from customer record ${sanitizeTerminalText(customer.record_id)} in ${where}; the record keeps the contact id under ${customer.external_source}.`);
33176
+ }
33177
+ var USAGE3, SUBCOMMANDS2;
33178
+ var init_contacts = __esm({
33179
+ "src/commands/contacts.ts"() {
33180
+ "use strict";
33181
+ init_auth();
33182
+ init_api_client();
33183
+ init_errors2();
33184
+ init_expected();
33185
+ init_repo_config();
33186
+ init_terminal_output();
33187
+ init_token_store();
33188
+ init_base_id();
33189
+ init_utils();
33190
+ USAGE3 = `
33191
+ wayai contacts \u2014 a contact's customer record in one of the organization's bases
33192
+
33193
+ Usage:
33194
+ wayai contacts link-customer <contact_id> --base <base_id> --record <record_id> [--org <org_id>] [--json]
33195
+ wayai contacts unlink-customer <contact_id> --base <base_id> [--org <org_id>] [--json]
33196
+
33197
+ link-customer Make the record the contact's customer record: a conversation with the
33198
+ contact (its WhatsApp phone, Instagram id or app account) then serves that
33199
+ customer through a customer-scoped toolset. The record is one of the base's
33200
+ customer record type (x-customer-scope role root), holding no external key
33201
+ or the contact id under another source. A record keyed under another
33202
+ external_id is refused: re-keying it would orphan its owned records.
33203
+ unlink-customer Unlink the contact's customer record in the base. The record keeps the
33204
+ contact id under the source wayai_contact_unlinked, so its owned records stay
33205
+ its own, and link-customer on the same record links it again.
33206
+
33207
+ The organization is --org, else this repo's (wayai-ws/wayai.yaml). You must be an
33208
+ organization admin. These commands need a browser sign-in (\`wayai login\`): an API
33209
+ token (\`wayai login --token\`, or WAYAI_TOKEN) is refused.
33210
+ `.trim();
33211
+ SUBCOMMANDS2 = ["link-customer", "unlink-customer"];
33212
+ }
33213
+ });
33214
+
33074
33215
  // ../../packages/core/dist/contracts/rekor-toolset.js
33075
33216
  var init_rekor_toolset = __esm({
33076
33217
  "../../packages/core/dist/contracts/rekor-toolset.js"() {
@@ -34040,14 +34181,14 @@ var init_plan = __esm({
34040
34181
 
34041
34182
  // src/knowledge/migrate.ts
34042
34183
  import { isDeepStrictEqual as isDeepStrictEqual3 } from "util";
34043
- async function resolveBases(kb, baseId) {
34044
- const base = await kb.getBase(baseId);
34045
- if (!base || base.deleted) throw expected(`Base "${safe(baseId)}" not found in this organization.`);
34184
+ async function resolveBases(kb, baseId2) {
34185
+ const base = await kb.getBase(baseId2);
34186
+ if (!base || base.deleted) throw expected(`Base "${safe(baseId2)}" not found in this organization.`);
34046
34187
  if (base.environment === "preview") {
34047
34188
  const origin = base.origin_base_id ? await kb.getBase(base.origin_base_id) : null;
34048
34189
  if (!origin || origin.deleted || origin.environment !== "production") {
34049
34190
  throw expected(
34050
- `Base "${safe(baseId)}" is a preview with no production origin, so its file types can never be promoted. Name the production knowledge base, or a preview created from it.`
34191
+ `Base "${safe(baseId2)}" is a preview with no production origin, so its file types can never be promoted. Name the production knowledge base, or a preview created from it.`
34051
34192
  );
34052
34193
  }
34053
34194
  return { production: origin.id, preview: base.id };
@@ -34060,7 +34201,7 @@ async function resolveBases(kb, baseId) {
34060
34201
  }
34061
34202
  if (previews.length !== 1) {
34062
34203
  throw expected(
34063
- previews.length === 0 ? `Base "${safe(baseId)}" has no preview to write its file types in. Create one with \`wayai bases create-preview ${safe(baseId)} --name <name>\`.` : `Base "${safe(baseId)}" has ${previews.length} previews (${previews.map(safe).join(", ")}). Pass the one to write its file types in as --base.`
34204
+ previews.length === 0 ? `Base "${safe(baseId2)}" has no preview to write its file types in. Create one with \`wayai bases create-preview ${safe(baseId2)} --name <name>\`.` : `Base "${safe(baseId2)}" has ${previews.length} previews (${previews.map(safe).join(", ")}). Pass the one to write its file types in as --base.`
34064
34205
  );
34065
34206
  }
34066
34207
  return { production: base.id, preview: previews[0] };
@@ -34513,28 +34654,28 @@ __export(knowledge_exports, {
34513
34654
  knowledgeCommand: () => knowledgeCommand,
34514
34655
  parseKnowledgeArgs: () => parseKnowledgeArgs
34515
34656
  });
34516
- import { parseArgs as parseArgs22 } from "util";
34517
- function usageError2(message) {
34657
+ import { parseArgs as parseArgs23 } from "util";
34658
+ function usageError3(message) {
34518
34659
  return expected(`${message}
34519
- ${USAGE3}`);
34660
+ ${USAGE4}`);
34520
34661
  }
34521
34662
  function readArgs(args2) {
34522
34663
  try {
34523
- return parseArgs22({ args: args2, options: OPTIONS, allowPositionals: true, strict: true });
34664
+ return parseArgs23({ args: args2, options: OPTIONS, allowPositionals: true, strict: true });
34524
34665
  } catch (err) {
34525
- throw usageError2(err instanceof Error ? err.message : String(err));
34666
+ throw usageError3(err instanceof Error ? err.message : String(err));
34526
34667
  }
34527
34668
  }
34528
34669
  function parseKnowledgeArgs(args2) {
34529
34670
  const { values, positionals } = readArgs(args2);
34530
34671
  const [verb, ...extra] = positionals;
34531
- if (verb !== "migrate") throw usageError2(verb === void 0 ? "No subcommand given." : `Unknown subcommand ${JSON.stringify(verb)}.`);
34532
- if (extra.length > 0) throw usageError2(`Unexpected argument ${JSON.stringify(extra[0])}.`);
34533
- if (!values.org) throw usageError2("--org <org_id> is required.");
34534
- if (!UUID_RE3.test(values.org)) throw usageError2(`Invalid --org ${JSON.stringify(values.org)}: expected an organization id (a UUID).`);
34535
- if (!values.base) throw usageError2("--base <knowledge base> is required.");
34672
+ if (verb !== "migrate") throw usageError3(verb === void 0 ? "No subcommand given." : `Unknown subcommand ${JSON.stringify(verb)}.`);
34673
+ if (extra.length > 0) throw usageError3(`Unexpected argument ${JSON.stringify(extra[0])}.`);
34674
+ if (!values.org) throw usageError3("--org <org_id> is required.");
34675
+ if (!UUID_RE3.test(values.org)) throw usageError3(`Invalid --org ${JSON.stringify(values.org)}: expected an organization id (a UUID).`);
34676
+ if (!values.base) throw usageError3("--base <knowledge base> is required.");
34536
34677
  if (values.hub !== void 0 && !UUID_RE3.test(values.hub)) {
34537
- throw usageError2(`Invalid --hub ${JSON.stringify(values.hub)}: expected a hub id (a UUID).`);
34678
+ throw usageError3(`Invalid --hub ${JSON.stringify(values.hub)}: expected a hub id (a UUID).`);
34538
34679
  }
34539
34680
  return {
34540
34681
  orgId: values.org,
@@ -34546,12 +34687,12 @@ function parseKnowledgeArgs(args2) {
34546
34687
  }
34547
34688
  async function knowledgeCommand(args2) {
34548
34689
  if (wantsHelp(args2) || args2.length === 0) {
34549
- console.log(USAGE3);
34690
+ console.log(USAGE4);
34550
34691
  return;
34551
34692
  }
34552
34693
  const options = parseKnowledgeArgs(args2);
34553
34694
  if (!options.dryRun && !options.yes && !isInteractive()) {
34554
- throw usageError2("It asks before it writes; pass -y when not running in a terminal, or --dry-run.");
34695
+ throw usageError3("It asks before it writes; pass -y when not running in a terminal, or --dry-run.");
34555
34696
  }
34556
34697
  const { config, accessToken } = await requireAuth();
34557
34698
  const api = new ApiClient({ apiUrl: config.api_url, accessToken, onUnauthorized: () => getAccessToken(config) });
@@ -34561,7 +34702,7 @@ async function knowledgeCommand(args2) {
34561
34702
  confirm
34562
34703
  });
34563
34704
  }
34564
- var USAGE3, OPTIONS;
34705
+ var USAGE4, OPTIONS;
34565
34706
  var init_knowledge = __esm({
34566
34707
  "src/commands/knowledge.ts"() {
34567
34708
  "use strict";
@@ -34573,7 +34714,7 @@ var init_knowledge = __esm({
34573
34714
  init_helpers();
34574
34715
  init_migrate2();
34575
34716
  init_remote();
34576
- USAGE3 = `
34717
+ USAGE4 = `
34577
34718
  wayai knowledge migrate \u2014 move knowledge resources into the organization's knowledge base
34578
34719
 
34579
34720
  Usage:
@@ -35244,8 +35385,8 @@ function parseScopedTargetFlags(flagArgs, usage3, opts = {}) {
35244
35385
  return { body: { scope: "hub", hub_id: hubId, dry_run: dryRun }, targetLabel: `hub ${hubId}`, dryRun, yes, jsonOutput };
35245
35386
  }
35246
35387
  async function runRepairTeamOrphans(flagArgs) {
35247
- const USAGE4 = "wayai admin hubs repair-team-orphans --all | --org <org_id> | --hub <hub_id> [--dry-run] [--yes] [--json]";
35248
- const { body, targetLabel, dryRun, yes, jsonOutput } = parseScopedTargetFlags(flagArgs, USAGE4);
35388
+ const USAGE5 = "wayai admin hubs repair-team-orphans --all | --org <org_id> | --hub <hub_id> [--dry-run] [--yes] [--json]";
35389
+ const { body, targetLabel, dryRun, yes, jsonOutput } = parseScopedTargetFlags(flagArgs, USAGE5);
35249
35390
  if (!dryRun && !yes && !jsonOutput) {
35250
35391
  console.log(`About to PURGE dangling team references in: ${targetLabel}.`);
35251
35392
  console.log("Memberships pointing at a deleted team are removed (HubDO + UserDO mirror); conversations pinned to one are unassigned.");
@@ -35291,7 +35432,7 @@ async function runRepairTeamOrphans(flagArgs) {
35291
35432
  }
35292
35433
  }
35293
35434
  async function runRepairBranchingOrphans(flagArgs) {
35294
- const USAGE4 = "wayai admin hubs repair-branching-orphans --all | --org <org_id> | --hub <hub_id> [--id <type>:<id> ...] [--dry-run] [--yes] [--json]";
35435
+ const USAGE5 = "wayai admin hubs repair-branching-orphans --all | --org <org_id> | --hub <hub_id> [--id <type>:<id> ...] [--dry-run] [--yes] [--json]";
35295
35436
  const targets = [];
35296
35437
  const scopeArgs = [];
35297
35438
  for (let i = 0; i < flagArgs.length; i++) {
@@ -35309,10 +35450,10 @@ async function runRepairBranchingOrphans(flagArgs) {
35309
35450
  }
35310
35451
  targets.push({ entity_type: entityType, entity_id: entityId });
35311
35452
  }
35312
- const { body, targetLabel, dryRun, yes, jsonOutput } = parseScopedTargetFlags(scopeArgs, USAGE4);
35453
+ const { body, targetLabel, dryRun, yes, jsonOutput } = parseScopedTargetFlags(scopeArgs, USAGE5);
35313
35454
  if (targets.length > 0 && body.scope !== "hub") {
35314
35455
  console.error("--id deletes rows of ONE production hub: combine it with --hub <hub_id>.");
35315
- console.error(USAGE4);
35456
+ console.error(USAGE5);
35316
35457
  process.exit(1);
35317
35458
  }
35318
35459
  if (targets.length > 0 && !dryRun && !yes && !jsonOutput) {
@@ -35374,8 +35515,8 @@ async function runRepairBranchingOrphans(flagArgs) {
35374
35515
  }
35375
35516
  }
35376
35517
  async function runRepairLegacyOrgGrants(flagArgs) {
35377
- const USAGE4 = "wayai admin orgs repair-legacy-grants --all | --org <org_id> [--dry-run] [--yes] [--json]";
35378
- const scoped = parseScopedTargetFlags(flagArgs, USAGE4, {
35518
+ const USAGE5 = "wayai admin orgs repair-legacy-grants --all | --org <org_id> [--dry-run] [--yes] [--json]";
35519
+ const scoped = parseScopedTargetFlags(flagArgs, USAGE5, {
35379
35520
  scopes: ["all", "org"],
35380
35521
  allLabel: "ALL organizations (platform-wide)"
35381
35522
  });
@@ -35427,8 +35568,8 @@ async function runRepairLegacyOrgGrants(flagArgs) {
35427
35568
  }
35428
35569
  }
35429
35570
  async function runHarnessMassDestroy(flagArgs) {
35430
- const USAGE4 = "wayai admin harness mass-destroy --all | --org <org_id> | --hub <hub_id> [--dry-run] [--yes] [--json]";
35431
- const { body, targetLabel, dryRun, yes, jsonOutput } = parseScopedTargetFlags(flagArgs, USAGE4);
35571
+ const USAGE5 = "wayai admin harness mass-destroy --all | --org <org_id> | --hub <hub_id> [--dry-run] [--yes] [--json]";
35572
+ const { body, targetLabel, dryRun, yes, jsonOutput } = parseScopedTargetFlags(flagArgs, USAGE5);
35432
35573
  if (!dryRun && !yes && !jsonOutput) {
35433
35574
  console.log(`About to REAP every live harness session / token / slot in: ${targetLabel}.`);
35434
35575
  console.log("This destroys running harness sessions and revokes their tokens. Run with --dry-run first to see the blast radius.");
@@ -37722,8 +37863,8 @@ function buildBasesReportCommand() {
37722
37863
  if (opts.errorMessage) body.error_message = opts.errorMessage;
37723
37864
  if (opts.context) body.context = opts.context;
37724
37865
  if (opts.reporterEmail) body.reporter_email = opts.reporterEmail;
37725
- const baseId = opts.baseId ?? findBase(this) ?? process.env.WAYAI_BASE;
37726
- if (baseId) body.base_id = baseId;
37866
+ const baseId2 = opts.baseId ?? findBase(this) ?? process.env.WAYAI_BASE;
37867
+ if (baseId2) body.base_id = baseId2;
37727
37868
  if (opts.recordType) body.record_type = opts.recordType;
37728
37869
  if (opts.recordId) body.record_id = opts.recordId;
37729
37870
  if (opts.externalId) body.external_id = opts.externalId;
@@ -38567,28 +38708,28 @@ function buildBasesCommand() {
38567
38708
  bases.command("use <base>").description(
38568
38709
  "Deprecated alias of `wayai use bases/<id>` \u2014 scope this worktree to a base"
38569
38710
  ).action(async function(selector) {
38570
- const baseId = resolveBaseSelectorToId(findGitRoot(), selector);
38711
+ const baseId2 = resolveBaseSelectorToId(findGitRoot(), selector);
38571
38712
  const previous = readScope().bases;
38572
- const changed = previous.length !== 1 || previous[0] !== baseId;
38713
+ const changed = previous.length !== 1 || previous[0] !== baseId2;
38573
38714
  if (changed) {
38574
38715
  try {
38575
- setScopeAxis("bases", [baseId]);
38716
+ setScopeAxis("bases", [baseId2]);
38576
38717
  } catch (err) {
38577
38718
  throw expected(err instanceof Error ? err.message : String(err));
38578
38719
  }
38579
38720
  }
38580
38721
  if (outputFormat(this) === "json") {
38581
38722
  printOutput(
38582
- { base_id: baseId, previous_base_id: previous[0] ?? null, changed },
38723
+ { base_id: baseId2, previous_base_id: previous[0] ?? null, changed },
38583
38724
  "json"
38584
38725
  );
38585
38726
  return;
38586
38727
  }
38587
38728
  if (!changed) {
38588
- console.log(`Worktree already bound to base ${baseId}.`);
38729
+ console.log(`Worktree already bound to base ${baseId2}.`);
38589
38730
  } else {
38590
38731
  console.log(
38591
- previous.length > 0 ? `Worktree rebound: ${previous.join(", ")} -> ${baseId}.` : `Worktree bound to base ${baseId}.`
38732
+ previous.length > 0 ? `Worktree rebound: ${previous.join(", ")} -> ${baseId2}.` : `Worktree bound to base ${baseId2}.`
38592
38733
  );
38593
38734
  }
38594
38735
  });
@@ -41017,6 +41158,11 @@ async function main() {
41017
41158
  await communitiesCommand2(args);
41018
41159
  break;
41019
41160
  }
41161
+ case "contacts": {
41162
+ const { contactsCommand: contactsCommand2 } = await Promise.resolve().then(() => (init_contacts(), contacts_exports));
41163
+ await contactsCommand2(args);
41164
+ break;
41165
+ }
41020
41166
  case "knowledge": {
41021
41167
  const { knowledgeCommand: knowledgeCommand2 } = await Promise.resolve().then(() => (init_knowledge(), knowledge_exports));
41022
41168
  await knowledgeCommand2(args);
@@ -41111,6 +41257,7 @@ Commands:
41111
41257
  sync-mcp Re-discover an MCP connection's tools (refresh stale schemas)
41112
41258
  list List organizations and hubs
41113
41259
  communities An organization's communities: list, join link (get/rotate/off), stats, access list (list/add/remove) \u2014 \`wayai communities --help\`
41260
+ contacts Link a contact to its customer record in a base, or unlink it (browser sign-in only) \u2014 \`wayai contacts --help\`
41114
41261
  knowledge migrate Move an organization's knowledge resources, then a hub's (--hub), into its knowledge base as file types and files \u2014 \`wayai knowledge --help\`
41115
41262
  report create Report a platform bug (submits to the triage queue)
41116
41263
  report edit Amend your own pending report (title/description/error/steps/context)