@iblai/iblai-js 2.5.9 → 2.5.10

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.
@@ -63606,7 +63606,7 @@ var profileAdmin$3 = {
63606
63606
  applicationsTab: "Applications",
63607
63607
  applicationsTabDescription: "Review applications to your organization and edit the questions applicants answer when they apply.",
63608
63608
  onboardingTab: "Onboarding",
63609
- onboardingTabDescription: "Choose the agent every new member of this platform meets when they arrive, and how it introduces itself."
63609
+ onboardingTabDescription: "Choose the agents new members of this platform can be onboarded by, how each introduces itself, and copy the link that opens it."
63610
63610
  };
63611
63611
  var profileAutoRechargeModal$3 = {
63612
63612
  title: "Manage Usage",
@@ -66642,24 +66642,39 @@ var onboardingUserOnboarding$3 = {
66642
66642
  continueToApp: "Continue"
66643
66643
  };
66644
66644
  var profileOnboardingTab$3 = {
66645
- editorTitle: "User onboarding agent",
66646
- editorDescription: "The agent every new member of this platform meets when they arrive.",
66645
+ editorTitle: "User onboarding agents",
66646
+ editorDescription: "The agents new members of this platform can be onboarded by.",
66647
66647
  loadError: "Could not load the onboarding settings.",
66648
66648
  save: "Save changes",
66649
66649
  saving: "Saving...",
66650
- savedToast: "Onboarding agent saved",
66651
- saveFailedToast: "Could not save the onboarding agent",
66650
+ savedToast: "Onboarding agents saved",
66651
+ saveFailedToast: "Could not save the onboarding agents",
66652
66652
  unsavedChanges: "Unsaved changes",
66653
- agentLabel: "Agent",
66653
+ agentLabel: "Agents",
66654
66654
  searchAgents: "Search agents",
66655
66655
  loadingAgents: "Loading agents...",
66656
66656
  noAgents: "No agents found.",
66657
- clearAgent: "Clear the selected agent",
66657
+ clearAgent: "Remove this agent",
66658
66658
  agentTitleLabel: "Heading",
66659
66659
  agentTitlePlaceholder: "Meet your assistant",
66660
66660
  agentDescriptionLabel: "Sub-heading",
66661
66661
  agentDescriptionPlaceholder: "Ask your assistant anything to get started.",
66662
- noAgentHint: "With no agent set, members skip onboarding entirely."
66662
+ noAgentHint: "With no agent set, members skip onboarding entirely.",
66663
+ copyLink: "Copy link",
66664
+ linkCopied: "Copied",
66665
+ defaultBadge: "Default",
66666
+ defaultBadgeHint: "Members who arrive without a link meet this agent.",
66667
+ emptyTitle: "No onboarding agent yet",
66668
+ emptyBody: "Search above to pick the agent new members meet when they arrive. Until then, they skip onboarding entirely.",
66669
+ moveUp: "Move up",
66670
+ moveDown: "Move down",
66671
+ linkLabel: "Onboarding link",
66672
+ introLabel: "Introduction",
66673
+ introSummary: "Heading and sub-heading shown above the agent",
66674
+ collapse: "Hide introduction",
66675
+ expand: "Edit introduction",
66676
+ oneAgent: "1 agent",
66677
+ multipleAgents: "{count} agents"
66663
66678
  };
66664
66679
  var en = {
66665
66680
  accessTabAddAccess: accessTabAddAccess$3,
@@ -70711,7 +70726,7 @@ var profileAdmin$2 = {
70711
70726
  applicationsTab: "Candidatures",
70712
70727
  applicationsTabDescription: "Consultez les candidatures à votre organisation et modifiez les questions auxquelles les candidats répondent lorsqu'ils postulent.",
70713
70728
  onboardingTab: "Intégration",
70714
- onboardingTabDescription: "Choisissez l'agent que rencontre chaque nouveau membre de cette plateforme à son arrivée, ainsi que sa présentation."
70729
+ onboardingTabDescription: "Choisissez les agents pouvant accompagner l'arrivée des nouveaux membres de cette plateforme, leur présentation, et copiez le lien qui les ouvre."
70715
70730
  };
70716
70731
  var profileAutoRechargeModal$2 = {
70717
70732
  title: "Gérer l'utilisation",
@@ -73581,24 +73596,39 @@ var onboardingUserOnboarding$2 = {
73581
73596
  continueToApp: "Continuer"
73582
73597
  };
73583
73598
  var profileOnboardingTab$2 = {
73584
- editorTitle: "Agent d'intégration des utilisateurs",
73585
- editorDescription: "L'agent que rencontre chaque nouveau membre de cette plateforme à son arrivée.",
73599
+ editorTitle: "Agents d'intégration des utilisateurs",
73600
+ editorDescription: "Les agents qui peuvent accompagner l'arrivée des nouveaux membres de cette plateforme.",
73586
73601
  loadError: "Impossible de charger les paramètres d'intégration.",
73587
73602
  save: "Enregistrer les modifications",
73588
73603
  saving: "Enregistrement...",
73589
- savedToast: "Agent d'intégration enregistré",
73590
- saveFailedToast: "Impossible d'enregistrer l'agent d'intégration",
73604
+ savedToast: "Agents d'intégration enregistrés",
73605
+ saveFailedToast: "Impossible d'enregistrer les agents d'intégration",
73591
73606
  unsavedChanges: "Modifications non enregistrées",
73592
- agentLabel: "Agent",
73607
+ agentLabel: "Agents",
73593
73608
  searchAgents: "Rechercher des agents",
73594
73609
  loadingAgents: "Chargement des agents...",
73595
73610
  noAgents: "Aucun agent trouvé.",
73596
- clearAgent: "Effacer l'agent sélectionné",
73611
+ clearAgent: "Retirer cet agent",
73597
73612
  agentTitleLabel: "Titre",
73598
73613
  agentTitlePlaceholder: "Rencontrez votre assistant",
73599
73614
  agentDescriptionLabel: "Sous-titre",
73600
73615
  agentDescriptionPlaceholder: "Posez toutes vos questions à votre assistant pour commencer.",
73601
- noAgentHint: "Sans agent défini, les membres ignorent complètement l'intégration."
73616
+ noAgentHint: "Sans agent défini, les membres ignorent complètement l'intégration.",
73617
+ copyLink: "Copier le lien",
73618
+ linkCopied: "Copié",
73619
+ defaultBadge: "Par défaut",
73620
+ defaultBadgeHint: "Les membres arrivant sans lien rencontrent cet agent.",
73621
+ emptyTitle: "Aucun agent d'intégration",
73622
+ emptyBody: "Cherchez ci-dessus l'agent que rencontreront les nouveaux membres à leur arrivée. D'ici là, ils passent l'intégration.",
73623
+ moveUp: "Monter",
73624
+ moveDown: "Descendre",
73625
+ linkLabel: "Lien d'intégration",
73626
+ introLabel: "Présentation",
73627
+ introSummary: "Titre et sous-titre affichés au-dessus de l'agent",
73628
+ collapse: "Masquer la présentation",
73629
+ expand: "Modifier la présentation",
73630
+ oneAgent: "1 agent",
73631
+ multipleAgents: "{count} agents"
73602
73632
  };
73603
73633
  var fr = {
73604
73634
  accessTabAddAccess: accessTabAddAccess$2,
@@ -77650,7 +77680,7 @@ var profileAdmin$1 = {
77650
77680
  applicationsTab: "Solicitudes",
77651
77681
  applicationsTabDescription: "Revise las solicitudes a su organización y edite las preguntas que responden los solicitantes cuando postulan.",
77652
77682
  onboardingTab: "Incorporación",
77653
- onboardingTabDescription: "Elija el agente que conoce cada nuevo miembro de esta plataforma al llegar y cómo se presenta."
77683
+ onboardingTabDescription: "Elija los agentes que pueden acompañar a los nuevos miembros de esta plataforma, cómo se presenta cada uno, y copie el enlace que lo abre."
77654
77684
  };
77655
77685
  var profileAutoRechargeModal$1 = {
77656
77686
  title: "Gestionar uso",
@@ -80520,24 +80550,39 @@ var onboardingUserOnboarding$1 = {
80520
80550
  continueToApp: "Continuar"
80521
80551
  };
80522
80552
  var profileOnboardingTab$1 = {
80523
- editorTitle: "Agente de incorporación de usuarios",
80524
- editorDescription: "El agente que conoce cada nuevo miembro de esta plataforma al llegar.",
80553
+ editorTitle: "Agentes de incorporación de usuarios",
80554
+ editorDescription: "Los agentes que pueden acompañar a los nuevos miembros de esta plataforma.",
80525
80555
  loadError: "No se pudo cargar la configuración de incorporación.",
80526
80556
  save: "Guardar cambios",
80527
80557
  saving: "Guardando...",
80528
- savedToast: "Agente de incorporación guardado",
80529
- saveFailedToast: "No se pudo guardar el agente de incorporación",
80558
+ savedToast: "Agentes de incorporación guardados",
80559
+ saveFailedToast: "No se pudieron guardar los agentes de incorporación",
80530
80560
  unsavedChanges: "Cambios sin guardar",
80531
- agentLabel: "Agente",
80561
+ agentLabel: "Agentes",
80532
80562
  searchAgents: "Buscar agentes",
80533
80563
  loadingAgents: "Cargando agentes...",
80534
80564
  noAgents: "No se encontraron agentes.",
80535
- clearAgent: "Quitar el agente seleccionado",
80565
+ clearAgent: "Quitar este agente",
80536
80566
  agentTitleLabel: "Encabezado",
80537
80567
  agentTitlePlaceholder: "Conozca a su asistente",
80538
80568
  agentDescriptionLabel: "Subtítulo",
80539
80569
  agentDescriptionPlaceholder: "Pregúntele lo que quiera a su asistente para empezar.",
80540
- noAgentHint: "Sin un agente definido, los miembros omiten por completo la incorporación."
80570
+ noAgentHint: "Sin un agente definido, los miembros omiten por completo la incorporación.",
80571
+ copyLink: "Copiar enlace",
80572
+ linkCopied: "Copiado",
80573
+ defaultBadge: "Predeterminado",
80574
+ defaultBadgeHint: "Los miembros que llegan sin enlace conocen a este agente.",
80575
+ emptyTitle: "Aún no hay agente de incorporación",
80576
+ emptyBody: "Busque arriba el agente que conocerán los nuevos miembros al llegar. Hasta entonces, omiten la incorporación.",
80577
+ moveUp: "Subir",
80578
+ moveDown: "Bajar",
80579
+ linkLabel: "Enlace de incorporación",
80580
+ introLabel: "Presentación",
80581
+ introSummary: "Título y subtítulo mostrados sobre el agente",
80582
+ collapse: "Ocultar presentación",
80583
+ expand: "Editar presentación",
80584
+ oneAgent: "1 agente",
80585
+ multipleAgents: "{count} agentes"
80541
80586
  };
80542
80587
  var es = {
80543
80588
  accessTabAddAccess: accessTabAddAccess$1,
@@ -84589,7 +84634,7 @@ var profileAdmin = {
84589
84634
  applicationsTab: "申请",
84590
84635
  applicationsTabDescription: "查看向贵组织提交的申请,并编辑申请人申请时回答的问题。",
84591
84636
  onboardingTab: "引导",
84592
- onboardingTabDescription: "选择本平台每位新成员进入时见到的智能体,以及它的介绍文案。"
84637
+ onboardingTabDescription: "选择可引导本平台新成员的助手、各自的介绍文案,并复制打开它的链接。"
84593
84638
  };
84594
84639
  var profileAutoRechargeModal = {
84595
84640
  title: "管理用量",
@@ -87459,24 +87504,39 @@ var onboardingUserOnboarding = {
87459
87504
  continueToApp: "继续"
87460
87505
  };
87461
87506
  var profileOnboardingTab = {
87462
- editorTitle: "用户引导智能体",
87463
- editorDescription: "本平台每位新成员进入时见到的智能体。",
87507
+ editorTitle: "用户引导助手",
87508
+ editorDescription: "可用于引导本平台新成员的助手。",
87464
87509
  loadError: "无法加载引导设置。",
87465
87510
  save: "保存更改",
87466
87511
  saving: "保存中…",
87467
- savedToast: "引导智能体已保存",
87468
- saveFailedToast: "无法保存引导智能体",
87512
+ savedToast: "引导助手已保存",
87513
+ saveFailedToast: "无法保存引导助手",
87469
87514
  unsavedChanges: "有未保存的更改",
87470
- agentLabel: "智能体",
87515
+ agentLabel: "助手",
87471
87516
  searchAgents: "搜索智能体",
87472
87517
  loadingAgents: "正在加载智能体…",
87473
87518
  noAgents: "未找到智能体。",
87474
- clearAgent: "清除所选智能体",
87519
+ clearAgent: "移除此助手",
87475
87520
  agentTitleLabel: "标题",
87476
87521
  agentTitlePlaceholder: "认识您的助手",
87477
87522
  agentDescriptionLabel: "副标题",
87478
87523
  agentDescriptionPlaceholder: "有任何问题都可以问您的助手。",
87479
- noAgentHint: "未设置智能体时,成员将完全跳过引导流程。"
87524
+ noAgentHint: "未设置智能体时,成员将完全跳过引导流程。",
87525
+ copyLink: "复制链接",
87526
+ linkCopied: "已复制",
87527
+ defaultBadge: "默认",
87528
+ defaultBadgeHint: "未通过链接进入的成员会见到该助手。",
87529
+ emptyTitle: "尚未设置引导助手",
87530
+ emptyBody: "在上方搜索新成员进入时要见到的助手。在此之前,他们将跳过引导。",
87531
+ moveUp: "上移",
87532
+ moveDown: "下移",
87533
+ linkLabel: "引导链接",
87534
+ introLabel: "介绍",
87535
+ introSummary: "显示在助手上方的标题与副标题",
87536
+ collapse: "隐藏介绍",
87537
+ expand: "编辑介绍",
87538
+ oneAgent: "1 个助手",
87539
+ multipleAgents: "{count} 个助手"
87480
87540
  };
87481
87541
  var zh = {
87482
87542
  accessTabAddAccess: accessTabAddAccess,
@@ -184621,31 +184681,91 @@ function Markdown({ children, className }) {
184621
184681
  }
184622
184682
 
184623
184683
  /**
184624
- * Single-select searchable picker: a deb-ounce-agnostic input + absolute
184684
+ * Whether the dropdown is open, closing on a pointer press outside `ref` or on
184685
+ * Escape.
184686
+ *
184687
+ * Deliberately NOT closed on the input's `blur`: a press anywhere inside the
184688
+ * panel — its scrollbar above all — blurs the input, so a blur-driven picker
184689
+ * shuts the moment you try to scroll the results. Watching for a press outside
184690
+ * instead means the panel stays put no matter where inside it you press, and
184691
+ * still closes for every gesture that means "I'm done here".
184692
+ */
184693
+ function useDismissable(ref) {
184694
+ const [isOpen, setIsOpen] = React__default.useState(false);
184695
+ React__default.useEffect(() => {
184696
+ if (!isOpen)
184697
+ return;
184698
+ const onPointerDown = (event) => {
184699
+ var _a;
184700
+ const target = event.target;
184701
+ // A press on a node already detached from the document (an option that
184702
+ // re-rendered under the pointer) is not a press outside.
184703
+ if (target && !target.isConnected)
184704
+ return;
184705
+ if (target && ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.contains(target)))
184706
+ return;
184707
+ setIsOpen(false);
184708
+ };
184709
+ const onKeyDown = (event) => {
184710
+ if (event.key === 'Escape')
184711
+ setIsOpen(false);
184712
+ };
184713
+ document.addEventListener('pointerdown', onPointerDown, true);
184714
+ document.addEventListener('keydown', onKeyDown);
184715
+ return () => {
184716
+ document.removeEventListener('pointerdown', onPointerDown, true);
184717
+ document.removeEventListener('keydown', onKeyDown);
184718
+ };
184719
+ }, [isOpen, ref]);
184720
+ return [isOpen, setIsOpen];
184721
+ }
184722
+ /** The search box plus its absolutely-positioned results panel. */
184723
+ function SearchField({ labels, searchTerm, onSearchTermChange, options, isLoading, minChars, isOpen, onOpen, onPick, testId, renderOptionSuffix, emptyHint, }) {
184724
+ return (jsxs("div", { className: "relative", children: [jsx(Input, { id: `${testId}-input`, className: "focus-visible:border-blue-500 focus-visible:ring-1 focus-visible:ring-blue-500", "aria-label": labels.label || labels.placeholder, value: searchTerm, onChange: (e) => {
184725
+ onSearchTermChange(e.target.value);
184726
+ onOpen();
184727
+ }, onFocus: onOpen, placeholder: labels.placeholder, autoComplete: "off", "aria-autocomplete": "list", "aria-expanded": isOpen, "data-testid": `${testId}-input` }), isOpen && (jsx("div", { className: "absolute top-full right-0 left-0 z-50 mt-1 max-h-64 overflow-y-auto overscroll-contain rounded-md border border-gray-200 bg-white shadow-lg", "data-testid": `${testId}-results`, children: searchTerm.trim().length < minChars ? (jsx("div", { className: "px-3 py-2 text-sm text-gray-600", children: labels.typeToSearch })) : isLoading ? (jsxs("div", { className: "flex items-center gap-2 px-3 py-2 text-sm text-gray-600", children: [jsx(LoaderCircle, { className: "h-3.5 w-3.5 animate-spin", "aria-hidden": "true" }), labels.searching] })) : options.length > 0 ? (options.map((option) => (jsxs("button", { type: "button", className: "flex w-full items-center justify-between gap-2 px-3 py-2 text-left hover:bg-gray-50", onClick: () => onPick(option), "data-testid": `${testId}-option-${option.value}`, children: [jsxs("span", { className: "flex min-w-0 flex-col items-start gap-0.5", children: [jsx("span", { className: "text-sm font-medium text-gray-900", children: option.label }), option.sublabel && (jsx("span", { className: "text-xs text-gray-600", children: option.sublabel }))] }), renderOptionSuffix === null || renderOptionSuffix === void 0 ? void 0 : renderOptionSuffix(option)] }, option.value)))) : (jsx("div", { className: "px-3 py-2 text-sm text-gray-600", "data-testid": `${testId}-no-results`, children: emptyHint !== null && emptyHint !== void 0 ? emptyHint : labels.noResults })) }))] }));
184728
+ }
184729
+ /**
184730
+ * Single-select searchable picker: a debounce-agnostic input + absolute
184625
184731
  * results dropdown (the add-access pattern), collapsing to a removable chip
184626
184732
  * once something is picked. The caller owns the search term and the fetched
184627
184733
  * options so any query hook can back it.
184734
+ *
184735
+ * See {@link MultiSearchSelect} to pick more than one.
184628
184736
  */
184629
184737
  function SearchSelect({ labels, selected, onSelect, onClear, searchTerm, onSearchTermChange, options, isLoading, minChars = 2, labelClassName = 'text-xs font-medium text-gray-700', testId, }) {
184630
- const [isOpen, setIsOpen] = React__default.useState(false);
184631
- const blurTimeout = React__default.useRef(null);
184632
- React__default.useEffect(() => () => {
184633
- if (blurTimeout.current)
184634
- clearTimeout(blurTimeout.current);
184635
- }, []);
184738
+ const containerRef = React__default.useRef(null);
184739
+ const [isOpen, setIsOpen] = useDismissable(containerRef);
184636
184740
  if (selected) {
184637
184741
  return (jsxs("div", { className: "space-y-1.5", children: [labels.label && jsx(Label$2, { className: labelClassName, children: labels.label }), jsxs("div", { className: "flex items-center justify-between gap-2 rounded-md border border-gray-200 bg-gray-50 px-3 py-2", "data-testid": `${testId}-selected`, children: [jsxs("div", { className: "min-w-0", children: [jsx("p", { className: "truncate text-sm font-medium text-gray-900", children: selected.label }), selected.sublabel && (jsx("p", { className: "truncate text-xs text-gray-600", children: selected.sublabel }))] }), jsxs(Button$1, { type: "button", size: "icon", variant: "ghost", className: "h-6 w-6 flex-shrink-0 text-gray-500 hover:text-red-600", onClick: onClear, "data-testid": `${testId}-clear`, children: [jsx(X$1, { className: "h-3.5 w-3.5", "aria-hidden": "true" }), jsx("span", { className: "sr-only", children: labels.clear })] })] })] }));
184638
184742
  }
184639
- return (jsxs("div", { className: "space-y-1.5", children: [labels.label && (jsx(Label$2, { className: labelClassName, htmlFor: `${testId}-input`, children: labels.label })), jsxs("div", { className: "relative", children: [jsx(Input, { id: `${testId}-input`, className: "focus-visible:border-blue-500 focus-visible:ring-1 focus-visible:ring-blue-500", "aria-label": labels.label || labels.placeholder, value: searchTerm, onChange: (e) => onSearchTermChange(e.target.value), onFocus: () => {
184640
- if (blurTimeout.current)
184641
- clearTimeout(blurTimeout.current);
184642
- setIsOpen(true);
184643
- }, onBlur: () => {
184644
- blurTimeout.current = setTimeout(() => setIsOpen(false), 100);
184645
- }, placeholder: labels.placeholder, autoComplete: "off", "aria-autocomplete": "list", "aria-expanded": isOpen, "data-testid": `${testId}-input` }), isOpen && (jsx("div", { className: "absolute top-full right-0 left-0 z-50 mt-1 max-h-64 overflow-y-auto rounded-md border border-gray-200 bg-white shadow-lg", "data-testid": `${testId}-results`, children: searchTerm.trim().length < minChars ? (jsx("div", { className: "px-3 py-2 text-sm text-gray-600", children: labels.typeToSearch })) : isLoading ? (jsxs("div", { className: "flex items-center gap-2 px-3 py-2 text-sm text-gray-600", children: [jsx(LoaderCircle, { className: "h-3.5 w-3.5 animate-spin", "aria-hidden": "true" }), labels.searching] })) : options.length > 0 ? (options.map((option) => (jsxs("button", { type: "button", className: "flex w-full flex-col items-start gap-0.5 px-3 py-2 text-left hover:bg-gray-50", onMouseDown: (event) => event.preventDefault(), onClick: () => {
184646
- onSelect(option);
184647
- setIsOpen(false);
184648
- }, "data-testid": `${testId}-option-${option.value}`, children: [jsx("span", { className: "text-sm font-medium text-gray-900", children: option.label }), option.sublabel && (jsx("span", { className: "text-xs text-gray-600", children: option.sublabel }))] }, option.value)))) : (jsx("div", { className: "px-3 py-2 text-sm text-gray-600", "data-testid": `${testId}-no-results`, children: labels.noResults })) }))] })] }));
184743
+ return (jsxs("div", { className: "space-y-1.5", ref: containerRef, children: [labels.label && (jsx(Label$2, { className: labelClassName, htmlFor: `${testId}-input`, children: labels.label })), jsx(SearchField, { labels: labels, searchTerm: searchTerm, onSearchTermChange: onSearchTermChange, options: options, isLoading: isLoading, minChars: minChars, isOpen: isOpen, onOpen: () => setIsOpen(true), onPick: (option) => {
184744
+ onSelect(option);
184745
+ setIsOpen(false);
184746
+ }, testId: testId })] }));
184747
+ }
184748
+ /**
184749
+ * The {@link SearchSelect} search box, picking any number of options.
184750
+ *
184751
+ * The input stays put rather than collapsing into the selection: picking is
184752
+ * usually not a one-off here, and a field that disappears after the first pick
184753
+ * gives no way to add a second. Options already picked stay listed and ticked,
184754
+ * so clicking one again removes it — the list doubles as the state of the
184755
+ * selection instead of silently shrinking as you go.
184756
+ */
184757
+ function MultiSearchSelect({ labels, selected, onSelect, onRemove, searchTerm, onSearchTermChange, options, isLoading, minChars = 2, labelClassName = 'text-xs font-medium text-gray-700', emptyHint, renderSelected, testId, }) {
184758
+ const containerRef = React__default.useRef(null);
184759
+ const [isOpen, setIsOpen] = useDismissable(containerRef);
184760
+ const picked = new Set(selected.map((option) => option.value));
184761
+ return (jsxs("div", { className: "space-y-1.5", ref: containerRef, children: [labels.label && (jsx(Label$2, { className: labelClassName, htmlFor: `${testId}-input`, children: labels.label })), jsx(SearchField, { labels: labels, searchTerm: searchTerm, onSearchTermChange: onSearchTermChange, options: options, isLoading: isLoading, minChars: minChars, isOpen: isOpen, onOpen: () => setIsOpen(true),
184762
+ // The panel stays open: picking one of several is the normal case here,
184763
+ // and reopening between each would make a set of picks a set of chores.
184764
+ onPick: (option) => (picked.has(option.value) ? onRemove(option.value) : onSelect(option)), testId: testId, renderOptionSuffix: (option) => picked.has(option.value) ? (jsx("span", { className: "shrink-0 text-xs font-medium text-blue-600", "data-testid": `${testId}-picked-${option.value}`, children: "\u2713" })) : null }), selected.length === 0
184765
+ ? emptyHint && jsx("p", { className: "text-xs text-gray-400", children: emptyHint })
184766
+ : renderSelected
184767
+ ? selected.map((option) => (jsx(React__default.Fragment, { children: renderSelected(option) }, option.value)))
184768
+ : selected.length > 0 && (jsx("div", { className: "flex flex-wrap gap-2", "data-testid": `${testId}-selected`, children: selected.map((option) => (jsxs("span", { className: cn('inline-flex items-center gap-1 rounded-full border border-gray-200', 'bg-gray-50 py-1 pr-1 pl-3 text-sm text-gray-900'), "data-testid": `${testId}-chip-${option.value}`, children: [jsx("span", { className: "truncate", children: option.label }), jsxs(Button$1, { type: "button", size: "icon", variant: "ghost", className: "h-5 w-5 shrink-0 text-gray-500 hover:text-red-600", onClick: () => onRemove(option.value), "data-testid": `${testId}-remove-${option.value}`, children: [jsx(X$1, { className: "h-3 w-3", "aria-hidden": "true" }), jsx("span", { className: "sr-only", children: labels.clear })] })] }, option.value))) }))] }));
184649
184769
  }
184650
184770
 
184651
184771
  /**
@@ -190366,6 +190486,7 @@ function emptyUserOnboardingForm(title = '') {
190366
190486
  enabled: false,
190367
190487
  title,
190368
190488
  sections: [],
190489
+ agents: [],
190369
190490
  agent: null,
190370
190491
  };
190371
190492
  }
@@ -190385,25 +190506,53 @@ function coerceOnboardingAgent(raw) {
190385
190506
  description: typeof value.description === 'string' ? value.description : undefined,
190386
190507
  };
190387
190508
  }
190509
+ /**
190510
+ * Defensive read of a stored agent list. Falls back to the legacy single
190511
+ * `agent` key when no list is stored, so a tenant configured before multi-agent
190512
+ * onboarding keeps working without a migration; unusable entries are dropped
190513
+ * rather than failing the whole read.
190514
+ */
190515
+ function coerceOnboardingAgents(rawAgents, rawAgent) {
190516
+ const value = parseMetadataValue(rawAgents);
190517
+ if (Array.isArray(value)) {
190518
+ const agents = value
190519
+ .map(coerceOnboardingAgent)
190520
+ .filter((agent) => !!agent);
190521
+ // De-duplicate: the same agent twice would give the admin two rows that
190522
+ // write to one another, and the learner an ambiguous link.
190523
+ const seen = new Set();
190524
+ return agents.filter((agent) => {
190525
+ if (seen.has(agent.mentor_unique_id))
190526
+ return false;
190527
+ seen.add(agent.mentor_unique_id);
190528
+ return true;
190529
+ });
190530
+ }
190531
+ const legacy = coerceOnboardingAgent(rawAgent);
190532
+ return legacy ? [legacy] : [];
190533
+ }
190388
190534
  /**
190389
190535
  * Defensive read of the stored form. Anything unrecognizable (missing key,
190390
190536
  * wrong type, unparseable string) reads as an empty, disabled form so both the
190391
190537
  * editor and the wizard always have something to work with.
190392
190538
  */
190393
190539
  function coerceUserOnboardingForm(raw) {
190540
+ var _a;
190394
190541
  const value = parseMetadataValue(raw);
190395
190542
  if (!isRecord(value))
190396
190543
  return emptyUserOnboardingForm();
190397
190544
  const sections = Array.isArray(value.sections)
190398
190545
  ? value.sections.filter((section) => isRecord(section) && Array.isArray(section.fields))
190399
190546
  : [];
190547
+ const agents = coerceOnboardingAgents(value.agents, value.agent);
190400
190548
  return {
190401
190549
  version: typeof value.version === 'number' ? value.version : USER_ONBOARDING_FORM_VERSION,
190402
190550
  enabled: value.enabled === true,
190403
190551
  title: typeof value.title === 'string' ? value.title : '',
190404
190552
  description: typeof value.description === 'string' ? value.description : undefined,
190405
190553
  sections,
190406
- agent: coerceOnboardingAgent(value.agent),
190554
+ agents,
190555
+ agent: (_a = agents[0]) !== null && _a !== void 0 ? _a : null,
190407
190556
  updated_at: typeof value.updated_at === 'string' ? value.updated_at : undefined,
190408
190557
  };
190409
190558
  }
@@ -190413,20 +190562,48 @@ function readUserOnboardingForm(metadata) {
190413
190562
  }
190414
190563
  /** Whether the flow has anything to show: at least one question, or an agent. */
190415
190564
  function hasOnboardingContent(form) {
190416
- return form.sections.some((section) => { var _a, _b; return ((_b = (_a = section.fields) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0; }) || !!form.agent;
190565
+ var _a, _b;
190566
+ return (form.sections.some((section) => { var _a, _b; return ((_b = (_a = section.fields) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0; }) ||
190567
+ ((_b = (_a = form.agents) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0);
190568
+ }
190569
+ /**
190570
+ * The agent a learner should meet.
190571
+ *
190572
+ * With an `agentId` — from an onboarding link like `/onboarding/<agent-id>` —
190573
+ * only that agent will do: an id that names no configured agent resolves to
190574
+ * `null` rather than quietly substituting another one, because a link handed
190575
+ * to a specific audience showing a different agent is worse than showing none.
190576
+ * Without one, the first configured agent stands in as the platform default.
190577
+ */
190578
+ function findOnboardingAgent(form, agentId) {
190579
+ var _a, _b, _c;
190580
+ const agents = (_a = form.agents) !== null && _a !== void 0 ? _a : [];
190581
+ if (!agentId)
190582
+ return (_b = agents[0]) !== null && _b !== void 0 ? _b : null;
190583
+ return (_c = agents.find((agent) => agent.mentor_unique_id === agentId)) !== null && _c !== void 0 ? _c : null;
190584
+ }
190585
+ /**
190586
+ * The learner-facing link for one onboarding agent: `<base>/onboarding/<id>`.
190587
+ * `base` is the host's own origin or path prefix — trailing slashes are the
190588
+ * caller's habit, not their intent, so they are trimmed rather than doubled up.
190589
+ */
190590
+ function buildOnboardingAgentPath(base, agentId) {
190591
+ return `${(base !== null && base !== void 0 ? base : '').replace(/\/+$/, '')}/onboarding/${encodeURIComponent(agentId)}`;
190417
190592
  }
190418
190593
  /**
190419
190594
  * Merge the form into the tenant metadata for a `PUT` (the endpoint replaces
190420
190595
  * the whole object, so untouched keys must ride along).
190421
190596
  */
190422
190597
  function buildUserOnboardingFormMetadata(metadata, form, updatedAt) {
190423
- var _a;
190598
+ var _a, _b, _c;
190424
190599
  return {
190425
190600
  ...(metadata !== null && metadata !== void 0 ? metadata : {}),
190426
190601
  [USER_ONBOARDING_FORM_SLUG]: {
190427
190602
  ...form,
190428
190603
  version: USER_ONBOARDING_FORM_VERSION,
190429
- agent: (_a = form.agent) !== null && _a !== void 0 ? _a : null,
190604
+ agents: (_a = form.agents) !== null && _a !== void 0 ? _a : [],
190605
+ // Mirrored, not authored: see the note on `UserOnboardingForm.agent`.
190606
+ agent: (_c = (_b = form.agents) === null || _b === void 0 ? void 0 : _b[0]) !== null && _c !== void 0 ? _c : null,
190430
190607
  updated_at: updatedAt,
190431
190608
  },
190432
190609
  };
@@ -190476,8 +190653,15 @@ function buildUserOnboardingSubmissionMetadata(metadata, username, responses, su
190476
190653
  }
190477
190654
 
190478
190655
  /**
190479
- * Onboarding management: which agent every new member of the platform
190480
- * meets, and how it is introduced (heading + sub-heading).
190656
+ * Onboarding management: which agents new members of the platform can be
190657
+ * onboarded by, and how each is introduced (heading + sub-heading).
190658
+ *
190659
+ * More than one agent may be configured. They are not shown in sequence — a
190660
+ * learner meets exactly one, picked by the agent id in the link they arrive
190661
+ * through (`<onboardingBasePath>/onboarding/<agent-id>`, the link the Copy
190662
+ * button here hands out), so a tenant can point different audiences at
190663
+ * different onboardings. Arriving without an id gets the first in the list,
190664
+ * which is why the list is ordered and its head marked as the default.
190481
190665
  *
190482
190666
  * The whole thing is one tenant-metadata key (`user_onboarding_form`), so
190483
190667
  * saving merges the choice in and PUTs the metadata back. The member-facing
@@ -190485,8 +190669,8 @@ function buildUserOnboardingSubmissionMetadata(metadata, username, responses, su
190485
190669
  * agent — and nothing at all when no agent is set, handing the user straight
190486
190670
  * back to the app.
190487
190671
  */
190488
- function OnboardingTab({ platformKey, username, }) {
190489
- var _a, _b, _c;
190672
+ function OnboardingTab({ platformKey, username, onboardingBasePath, }) {
190673
+ var _a;
190490
190674
  const t = useT();
190491
190675
  const { data, isLoading, error } = useGetTenantMetadataQuery([{ org: platformKey }], {
190492
190676
  skip: !platformKey,
@@ -190504,24 +190688,39 @@ function OnboardingTab({ platformKey, username, }) {
190504
190688
  return '';
190505
190689
  }
190506
190690
  }, [username]);
190507
- const [agent, setAgent] = React.useState(null);
190691
+ const [agents, setAgents] = React.useState([]);
190508
190692
  const [dirty, setDirty] = React.useState(false);
190509
190693
  // Seed from the saved metadata, and re-seed when a refetch brings a newer
190510
190694
  // saved version.
190511
190695
  const saved = readUserOnboardingForm(metadata);
190512
190696
  const savedAt = saved.updated_at;
190513
190697
  React.useEffect(() => {
190514
- var _a;
190515
190698
  if (!metadata)
190516
190699
  return;
190517
- setAgent((_a = readUserOnboardingForm(metadata).agent) !== null && _a !== void 0 ? _a : null);
190700
+ setAgents(readUserOnboardingForm(metadata).agents);
190518
190701
  setDirty(false);
190519
190702
  // eslint-disable-next-line react-hooks/exhaustive-deps
190520
190703
  }, [!!metadata, savedAt]);
190521
190704
  const update = (next) => {
190522
- setAgent(next);
190705
+ setAgents(next);
190523
190706
  setDirty(true);
190524
190707
  };
190708
+ const addAgent = (option) => update([...agents, { mentor_unique_id: option.value, name: option.label }]);
190709
+ const removeAgent = (agentId) => update(agents.filter((agent) => agent.mentor_unique_id !== agentId));
190710
+ const patchAgent = (agentId, patch) => update(agents.map((agent) => (agent.mentor_unique_id === agentId ? { ...agent, ...patch } : agent)));
190711
+ /**
190712
+ * Move an agent one place along the list. Order is not decoration: the head
190713
+ * of the list is the agent a member meets when they arrive with no link, so
190714
+ * this is how an admin picks which onboarding is the platform default.
190715
+ */
190716
+ const moveAgent = (index, delta) => {
190717
+ const target = index + delta;
190718
+ if (target < 0 || target >= agents.length)
190719
+ return;
190720
+ const next = [...agents];
190721
+ [next[index], next[target]] = [next[target], next[index]];
190722
+ update(next);
190723
+ };
190525
190724
  // Agent search — the endpoint filters server-side, so only the term is local.
190526
190725
  const [searchTerm, setSearchTerm] = React.useState('');
190527
190726
  const [debouncedTerm, setDebouncedTerm] = React.useState('');
@@ -190568,9 +190767,9 @@ function OnboardingTab({ platformKey, username, }) {
190568
190767
  metadata: buildUserOnboardingFormMetadata(latest, {
190569
190768
  ...emptyUserOnboardingForm(),
190570
190769
  // An agent IS the onboarding here: picking one turns the flow
190571
- // on, clearing it turns the flow off.
190572
- enabled: !!agent,
190573
- agent,
190770
+ // on, clearing them all turns the flow off.
190771
+ enabled: agents.length > 0,
190772
+ agents,
190574
190773
  }, new Date().toISOString()),
190575
190774
  },
190576
190775
  },
@@ -190583,26 +190782,84 @@ function OnboardingTab({ platformKey, username, }) {
190583
190782
  }
190584
190783
  };
190585
190784
  if (isLoading) {
190586
- return (jsxs("div", { className: "space-y-4 pt-4", children: [jsx(Skeleton, { className: "h-8 w-56" }), jsx(Skeleton, { className: "h-40 w-full" })] }));
190785
+ return (jsxs("div", { className: "space-y-4 pt-4", children: [jsx(Skeleton, { className: "h-11 w-full rounded-xl" }), jsx(Skeleton, { className: "h-28 w-full rounded-xl" }), jsx(Skeleton, { className: "h-28 w-full rounded-xl" })] }));
190587
190786
  }
190588
190787
  if (error) {
190589
190788
  return jsx("p", { className: "pt-4 text-sm text-red-600", children: t('profileOnboardingTab.loadError') });
190590
190789
  }
190591
- return (jsxs("div", { className: "space-y-5 pt-4", children: [jsxs("div", { className: "space-y-4 rounded-xl border border-gray-200 bg-white p-5 shadow-sm dark:border-gray-700 dark:bg-gray-900", children: [jsx(SearchSelect, { testId: "onboarding-agent", labels: {
190592
- label: t('profileOnboardingTab.agentLabel'),
190593
- placeholder: t('profileOnboardingTab.searchAgents'),
190594
- typeToSearch: t('profileOnboardingTab.searchAgents'),
190595
- searching: t('profileOnboardingTab.loadingAgents'),
190596
- noResults: t('profileOnboardingTab.noAgents'),
190597
- clear: t('profileOnboardingTab.clearAgent'),
190598
- },
190599
- // Focusing shows the platform's agents straight away; typing filters.
190600
- minChars: 0,
190601
- // The picker's own compact label would sit a size below the Heading
190602
- // and Sub-heading fields beside it; match them instead.
190603
- labelClassName: "text-sm font-medium", selected: agent
190604
- ? { value: agent.mentor_unique_id, label: agent.name || agent.mentor_unique_id }
190605
- : null, onSelect: (option) => update({ ...(agent !== null && agent !== void 0 ? agent : {}), mentor_unique_id: option.value, name: option.label }), onClear: () => update(null), searchTerm: searchTerm, onSearchTermChange: setSearchTerm, options: options, isLoading: isSearching }), agent && (jsxs("div", { className: "grid gap-3 sm:grid-cols-2", children: [jsxs("div", { className: "space-y-1.5", children: [jsx(Label$2, { htmlFor: "onboarding-agent-title", children: t('profileOnboardingTab.agentTitleLabel') }), jsx(Input, { id: "onboarding-agent-title", value: (_b = agent.title) !== null && _b !== void 0 ? _b : '', placeholder: t('profileOnboardingTab.agentTitlePlaceholder'), onChange: (event) => update({ ...agent, title: event.target.value }) })] }), jsxs("div", { className: "space-y-1.5", children: [jsx(Label$2, { htmlFor: "onboarding-agent-description", children: t('profileOnboardingTab.agentDescriptionLabel') }), jsx(Input, { id: "onboarding-agent-description", value: (_c = agent.description) !== null && _c !== void 0 ? _c : '', placeholder: t('profileOnboardingTab.agentDescriptionPlaceholder'), onChange: (event) => update({ ...agent, description: event.target.value }) })] })] })), !agent && jsx("p", { className: "text-xs text-gray-400", children: t('profileOnboardingTab.noAgentHint') })] }), jsxs("div", { className: "flex flex-wrap items-center justify-end gap-3", children: [dirty && (jsx("span", { className: "text-xs text-amber-600", children: t('profileOnboardingTab.unsavedChanges') })), jsx(Button$1, { onClick: handleSave, disabled: saving, className: "bg-gradient-to-r from-blue-600 to-blue-400 text-white hover:opacity-90", children: saving ? t('profileOnboardingTab.saving') : t('profileOnboardingTab.save') })] })] }));
190790
+ return (jsxs("div", { className: "space-y-4 pt-4", children: [jsx("div", { className: "rounded-xl border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-700 dark:bg-gray-900", children: jsx(MultiSearchSelect, { testId: "onboarding-agent", labels: {
190791
+ label: t('profileOnboardingTab.agentLabel'),
190792
+ placeholder: t('profileOnboardingTab.searchAgents'),
190793
+ typeToSearch: t('profileOnboardingTab.searchAgents'),
190794
+ searching: t('profileOnboardingTab.loadingAgents'),
190795
+ noResults: t('profileOnboardingTab.noAgents'),
190796
+ clear: t('profileOnboardingTab.clearAgent'),
190797
+ },
190798
+ // Focusing shows the platform's agents straight away; typing filters.
190799
+ minChars: 0, labelClassName: "text-sm font-medium", selected: agents.map((agent) => ({
190800
+ value: agent.mentor_unique_id,
190801
+ label: agent.name || agent.mentor_unique_id,
190802
+ })), onSelect: addAgent, onRemove: removeAgent, searchTerm: searchTerm, onSearchTermChange: setSearchTerm, options: options, isLoading: isSearching,
190803
+ // The list below IS the selection; chips above it would say the same
190804
+ // thing twice.
190805
+ renderSelected: () => null }) }), agents.length === 0 ? (jsx(EmptyState, {})) : (jsxs("div", { className: "space-y-3", "data-testid": "onboarding-agent-list", children: [jsx("div", { className: "flex items-center justify-between px-1", children: jsx("p", { className: "text-xs font-medium tracking-wide text-gray-500 uppercase", children: agents.length === 1
190806
+ ? t('profileOnboardingTab.oneAgent')
190807
+ : t('profileOnboardingTab.multipleAgents', { count: agents.length }) }) }), agents.map((agent, index) => (jsx(AgentCard, { agent: agent, basePath: onboardingBasePath, isDefault: index === 0, canMoveUp: index > 0, canMoveDown: index < agents.length - 1, onMove: (delta) => moveAgent(index, delta), onRemove: () => removeAgent(agent.mentor_unique_id), onPatch: (patch) => patchAgent(agent.mentor_unique_id, patch) }, agent.mentor_unique_id)))] })), jsxs("div", { className: "flex flex-wrap items-center justify-end gap-3 pt-1", children: [dirty && (jsx("span", { className: "text-xs text-amber-600", children: t('profileOnboardingTab.unsavedChanges') })), jsx(Button$1, { onClick: handleSave, disabled: saving, className: "bg-gradient-to-r from-blue-600 to-blue-400 text-white hover:opacity-90", children: saving ? t('profileOnboardingTab.saving') : t('profileOnboardingTab.save') })] })] }));
190808
+ }
190809
+ /**
190810
+ * What the page says before anything is configured. Named as a state of its own
190811
+ * rather than a hint under the search box, because it is also the answer to
190812
+ * "what happens to members right now" — nothing, they skip onboarding.
190813
+ */
190814
+ function EmptyState() {
190815
+ const t = useT();
190816
+ return (jsxs("div", { className: "flex flex-col items-center rounded-xl border border-dashed border-gray-300 bg-gray-50/60 px-6 py-10 text-center dark:border-gray-700 dark:bg-gray-800/40", "data-testid": "onboarding-agent-empty", children: [jsx("span", { className: "mb-3 flex h-11 w-11 items-center justify-center rounded-xl bg-gradient-to-br from-blue-600 to-blue-400 text-white", children: jsx(UserPlus, { className: "h-5 w-5", "aria-hidden": "true" }) }), jsx("p", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: t('profileOnboardingTab.emptyTitle') }), jsx("p", { className: "mt-1 max-w-sm text-xs text-gray-500", children: t('profileOnboardingTab.emptyBody') })] }));
190817
+ }
190818
+ /**
190819
+ * One configured agent: who it is, where it sits in the order, the link that
190820
+ * opens it, and — behind a disclosure — the heading and sub-heading shown above
190821
+ * it in the flow. The introduction is tucked away because it is the part an
190822
+ * admin sets once; the link is the part they come back for.
190823
+ */
190824
+ function AgentCard({ agent, basePath, isDefault, canMoveUp, canMoveDown, onMove, onRemove, onPatch, }) {
190825
+ var _a, _b;
190826
+ const t = useT();
190827
+ const id = agent.mentor_unique_id;
190828
+ const titleId = `onboarding-agent-title-${id}`;
190829
+ const descriptionId = `onboarding-agent-description-${id}`;
190830
+ // Open by default: nothing is hidden from an admin who has just added an
190831
+ // agent, and a long list can be tidied away card by card.
190832
+ const [open, setOpen] = React.useState(true);
190833
+ const name = agent.name || id;
190834
+ return (jsxs("div", { className: "overflow-hidden rounded-xl border border-gray-200 bg-white shadow-sm transition-shadow hover:shadow-md dark:border-gray-700 dark:bg-gray-900", "data-testid": `onboarding-agent-card-${id}`, children: [jsxs("div", { className: "flex items-start gap-3 p-4", children: [jsx("span", { className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-gradient-to-br from-blue-600 to-blue-400 text-sm font-semibold text-white", "aria-hidden": "true", children: name.trim().charAt(0).toUpperCase() || '?' }), jsxs("div", { className: "min-w-0 flex-1", children: [jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [jsx("p", { className: "truncate text-sm font-semibold text-gray-900 dark:text-gray-100", children: name }), isDefault && (jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-blue-50 px-2 py-0.5 text-[11px] font-medium text-blue-700 dark:bg-blue-950 dark:text-blue-300", title: t('profileOnboardingTab.defaultBadgeHint'), "data-testid": `onboarding-agent-default-${id}`, children: [jsx(Sparkles, { className: "h-3 w-3", "aria-hidden": "true" }), t('profileOnboardingTab.defaultBadge')] }))] }), jsx("p", { className: "truncate text-xs text-gray-500", children: id })] }), jsxs("div", { className: "flex shrink-0 items-center gap-0.5", children: [(canMoveUp || canMoveDown) && (jsxs(Fragment$1, { children: [jsx(IconButton, { label: t('profileOnboardingTab.moveUp'), disabled: !canMoveUp, onClick: () => onMove(-1), testId: `onboarding-agent-move-up-${id}`, children: jsx(ChevronDown, { className: "h-3.5 w-3.5 rotate-180", "aria-hidden": "true" }) }), jsx(IconButton, { label: t('profileOnboardingTab.moveDown'), disabled: !canMoveDown, onClick: () => onMove(1), testId: `onboarding-agent-move-down-${id}`, children: jsx(ChevronDown, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) })] })), jsx(IconButton, { label: t('profileOnboardingTab.clearAgent'), onClick: onRemove, testId: `onboarding-agent-remove-${id}`, className: "hover:text-red-600", children: jsx(Trash2, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) })] })] }), jsx("div", { className: "border-t border-gray-100 px-4 py-3 dark:border-gray-800", children: jsx(CopyLink, { agentId: id, basePath: basePath }) }), jsxs("div", { className: "border-t border-gray-100 dark:border-gray-800", children: [jsxs("button", { type: "button", onClick: () => setOpen((value) => !value), "aria-expanded": open, "aria-controls": `onboarding-agent-intro-${id}`, className: "flex w-full items-center justify-between px-4 py-2.5 text-left text-xs font-medium text-gray-600 transition-colors hover:bg-gray-50 dark:text-gray-300 dark:hover:bg-gray-800", "data-testid": `onboarding-agent-intro-toggle-${id}`, children: [jsxs("span", { className: "flex min-w-0 flex-col", children: [jsx("span", { children: t('profileOnboardingTab.introLabel') }), jsx("span", { className: "truncate text-[11px] font-normal text-gray-400", children: agent.title || t('profileOnboardingTab.introSummary') })] }), jsx(ChevronDown, { className: cn('h-4 w-4 shrink-0 transition-transform', open && 'rotate-180'), "aria-hidden": "true" })] }), open && (jsxs("div", { id: `onboarding-agent-intro-${id}`, className: "grid gap-3 px-4 pt-1 pb-4 sm:grid-cols-2", children: [jsxs("div", { className: "space-y-1.5", children: [jsx(Label$2, { htmlFor: titleId, children: t('profileOnboardingTab.agentTitleLabel') }), jsx(Input, { id: titleId, value: (_a = agent.title) !== null && _a !== void 0 ? _a : '', placeholder: t('profileOnboardingTab.agentTitlePlaceholder'), onChange: (event) => onPatch({ title: event.target.value }) })] }), jsxs("div", { className: "space-y-1.5", children: [jsx(Label$2, { htmlFor: descriptionId, children: t('profileOnboardingTab.agentDescriptionLabel') }), jsx(Input, { id: descriptionId, value: (_b = agent.description) !== null && _b !== void 0 ? _b : '', placeholder: t('profileOnboardingTab.agentDescriptionPlaceholder'), onChange: (event) => onPatch({ description: event.target.value }) })] })] }))] })] }));
190835
+ }
190836
+ /** A square, icon-only action with its name left to assistive tech. */
190837
+ function IconButton({ label, onClick, disabled, testId, className, children, }) {
190838
+ return (jsxs(Button$1, { type: "button", size: "icon", variant: "ghost", className: cn('h-7 w-7 text-gray-400 hover:text-gray-700', className), disabled: disabled, onClick: onClick, title: label, "data-testid": testId, children: [children, jsx("span", { className: "sr-only", children: label })] }));
190839
+ }
190840
+ /** The agent's onboarding link, shown in full and copyable in one press. */
190841
+ function CopyLink({ agentId, basePath }) {
190842
+ const t = useT();
190843
+ const [copied, setCopied] = React.useState(false);
190844
+ // The browser's origin is the right default whenever the admin panel and the
190845
+ // learner-facing onboarding are one deployment; SSR has no origin to read, so
190846
+ // the link resolves on the client.
190847
+ const [origin, setOrigin] = React.useState('');
190848
+ React.useEffect(() => {
190849
+ setOrigin(window.location.origin);
190850
+ }, []);
190851
+ const link = buildOnboardingAgentPath(basePath || origin, agentId);
190852
+ const handleCopy = async () => {
190853
+ try {
190854
+ await navigator.clipboard.writeText(link);
190855
+ setCopied(true);
190856
+ setTimeout(() => setCopied(false), 2000);
190857
+ }
190858
+ catch (_a) {
190859
+ /* Clipboard unavailable (permissions/insecure context). */
190860
+ }
190861
+ };
190862
+ return (jsxs("div", { className: "flex items-center gap-2", children: [jsx(Link2, { className: "h-3.5 w-3.5 shrink-0 text-gray-400", "aria-hidden": "true" }), jsx("code", { className: "min-w-0 flex-1 truncate font-mono text-xs text-gray-600 dark:text-gray-300", title: link, "data-testid": `onboarding-agent-link-${agentId}`, children: link }), jsxs(Button$1, { type: "button", size: "sm", variant: "outline", className: cn('h-7 shrink-0 text-xs transition-colors', copied && 'border-green-200 bg-green-50 text-green-700 hover:bg-green-50'), onClick: handleCopy, "data-testid": `onboarding-agent-copy-${agentId}`, children: [copied ? (jsx(Check, { className: "mr-1.5 h-3.5 w-3.5", "aria-hidden": "true" })) : (jsx(Copy, { className: "mr-1.5 h-3.5 w-3.5", "aria-hidden": "true" })), copied ? t('profileOnboardingTab.linkCopied') : t('profileOnboardingTab.copyLink')] })] }));
190606
190863
  }
190607
190864
 
190608
190865
  const TabDescription = ({ icon, title, children }) => {
@@ -190610,9 +190867,9 @@ const TabDescription = ({ icon, title, children }) => {
190610
190867
  const [expanded, setExpanded] = useState(false);
190611
190868
  return (jsxs("div", { className: "flex gap-3 items-start border rounded-lg p-4 bg-blue-50/60 border-blue-100", children: [jsx("div", { className: "shrink-0 w-9 h-9 rounded-md flex items-center justify-center bg-blue-100 text-blue-600", children: icon }), jsxs("div", { className: "flex-1 min-w-0", children: [jsx("h3", { className: "text-sm font-semibold mb-1 text-blue-900 hidden sm:block", children: title }), jsx("p", { className: `text-sm text-gray-600 leading-relaxed sm:line-clamp-none! ${expanded ? '' : 'line-clamp-2'}`, children: children }), jsx("button", { type: "button", onClick: () => setExpanded((prev) => !prev), className: "mt-1 text-xs font-medium text-blue-700 hover:text-blue-800 sm:hidden", children: expanded ? t('profileAdmin.readLess') : t('profileAdmin.readMore') })] })] }));
190612
190869
  };
190613
- const Admin = ({ tenant, onInviteClick, hasUserTabPermission = false, hasGroupsTabPermission = false, hasRolesTabPermission = false, hasPoliciesTabPermission = false, hasTeamsTabPermission = false, hasAlertsTabPermission = false, hasInviteUserPermission = false, hasCreateTeamPermission = false, onLoadGroupPermissions, rbacPermissions = {}, enableRbac = false, showGradebookTab = false, currentSpa, authSpaUrl, }) => {
190870
+ const Admin = ({ tenant, onInviteClick, hasUserTabPermission = false, hasGroupsTabPermission = false, hasRolesTabPermission = false, hasPoliciesTabPermission = false, hasTeamsTabPermission = false, hasAlertsTabPermission = false, hasInviteUserPermission = false, hasCreateTeamPermission = false, onLoadGroupPermissions, rbacPermissions = {}, enableRbac = false, showGradebookTab = false, currentSpa, authSpaUrl, onboardingBasePath, }) => {
190614
190871
  const t = useT();
190615
- return (jsx("div", { className: "border border-gray-200 rounded-lg p-6", children: jsxs(Tabs, { defaultValue: "users", "aria-label": t('profileAdmin.rbacManagementTabsAriaLabel'), children: [jsxs(TabsList, { "aria-label": t('profileAdmin.managementTabsAriaLabel'), className: "max-w-full overflow-x-auto justify-start px-1", children: [hasUserTabPermission && (jsx(TabsTrigger, { value: "users", children: t('profileAdmin.usersTab') })), hasGroupsTabPermission && (jsx(TabsTrigger, { value: "groups", children: t('profileAdmin.groupsTab') })), hasRolesTabPermission && (jsx(TabsTrigger, { value: "roles", children: t('profileAdmin.rolesTab') })), hasPoliciesTabPermission && (jsx(TabsTrigger, { value: "policies", children: t('profileAdmin.policiesTab') })), hasTeamsTabPermission && (jsx(TabsTrigger, { value: "teams", children: t('profileAdmin.teamsTab') })), hasAlertsTabPermission && (jsx(TabsTrigger, { value: "alerts", children: t('profileAdmin.alertsTab') })), jsx(TabsTrigger, { value: "applications", children: t('profileAdmin.applicationsTab') }), jsx(TabsTrigger, { value: "onboarding", children: t('profileAdmin.onboardingTab') })] }), hasUserTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "users", children: [jsx(TabDescription, { icon: jsx(Users, { className: "w-5 h-5" }), title: t('profileAdmin.usersTab'), children: t('profileAdmin.usersDescription') }), jsx(UsersTab, { tenant: tenant, onInviteClick: onInviteClick, currentSpa: currentSpa, showGradebookTab: showGradebookTab })] })), hasGroupsTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "groups", children: [jsx(TabDescription, { icon: jsx(UsersRound, { className: "w-5 h-5" }), title: t('profileAdmin.groupsTab'), children: t('profileAdmin.groupsDescription') }), jsx(GroupsTab, { tenant: tenant })] })), hasRolesTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "roles", children: [jsx(TabDescription, { icon: jsx(UserCog, { className: "w-5 h-5" }), title: t('profileAdmin.rolesTab'), children: t('profileAdmin.rolesDescription') }), jsx(RolesTab, { tenant: tenant })] })), hasPoliciesTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "policies", children: [jsx(TabDescription, { icon: jsx(ScrollText, { className: "w-5 h-5" }), title: t('profileAdmin.policiesTab'), children: t('profileAdmin.policiesDescription') }), jsx(PoliciesTab, { tenant: tenant })] })), hasTeamsTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "teams", children: [jsx(TabDescription, { icon: jsx(Shield, { className: "w-5 h-5" }), title: t('profileAdmin.teamsTab'), children: t('profileAdmin.teamsDescription') }), jsx(GroupsTab, { tenant: tenant, isTeam: true, onInviteClick: onInviteClick, hasInviteUserPermission: hasInviteUserPermission, hasCreateTeamPermission: hasCreateTeamPermission, onLoadGroupPermissions: onLoadGroupPermissions, rbacPermissions: rbacPermissions, enableRbac: enableRbac })] })), hasAlertsTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "alerts", children: [jsx(TabDescription, { icon: jsx(BellRing, { className: "w-5 h-5" }), title: t('profileAdmin.alertsTab'), children: t('profileAdmin.alertsDescription') }), jsx(AlertsTab$1, { tenant: tenant })] })), jsxs(TabsContent, { className: "mt-4", value: "applications", children: [jsx(TabDescription, { icon: jsx(ClipboardList, { className: "w-5 h-5" }), title: t('profileAdmin.applicationsTab'), children: t('profileAdmin.applicationsTabDescription') }), jsx(ApplicationsTab, { platformKey: tenant, authSpaUrl: authSpaUrl })] }), jsxs(TabsContent, { className: "mt-4", value: "onboarding", children: [jsx(TabDescription, { icon: jsx(UserPlus, { className: "w-5 h-5" }), title: t('profileAdmin.onboardingTab'), children: t('profileAdmin.onboardingTabDescription') }), jsx(OnboardingTab, { platformKey: tenant })] })] }) }));
190872
+ return (jsx("div", { className: "border border-gray-200 rounded-lg p-6", children: jsxs(Tabs, { defaultValue: "users", "aria-label": t('profileAdmin.rbacManagementTabsAriaLabel'), children: [jsxs(TabsList, { "aria-label": t('profileAdmin.managementTabsAriaLabel'), className: "max-w-full overflow-x-auto justify-start px-1", children: [hasUserTabPermission && (jsx(TabsTrigger, { value: "users", children: t('profileAdmin.usersTab') })), hasGroupsTabPermission && (jsx(TabsTrigger, { value: "groups", children: t('profileAdmin.groupsTab') })), hasRolesTabPermission && (jsx(TabsTrigger, { value: "roles", children: t('profileAdmin.rolesTab') })), hasPoliciesTabPermission && (jsx(TabsTrigger, { value: "policies", children: t('profileAdmin.policiesTab') })), hasTeamsTabPermission && (jsx(TabsTrigger, { value: "teams", children: t('profileAdmin.teamsTab') })), hasAlertsTabPermission && (jsx(TabsTrigger, { value: "alerts", children: t('profileAdmin.alertsTab') })), jsx(TabsTrigger, { value: "applications", children: t('profileAdmin.applicationsTab') }), jsx(TabsTrigger, { value: "onboarding", children: t('profileAdmin.onboardingTab') })] }), hasUserTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "users", children: [jsx(TabDescription, { icon: jsx(Users, { className: "w-5 h-5" }), title: t('profileAdmin.usersTab'), children: t('profileAdmin.usersDescription') }), jsx(UsersTab, { tenant: tenant, onInviteClick: onInviteClick, currentSpa: currentSpa, showGradebookTab: showGradebookTab })] })), hasGroupsTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "groups", children: [jsx(TabDescription, { icon: jsx(UsersRound, { className: "w-5 h-5" }), title: t('profileAdmin.groupsTab'), children: t('profileAdmin.groupsDescription') }), jsx(GroupsTab, { tenant: tenant })] })), hasRolesTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "roles", children: [jsx(TabDescription, { icon: jsx(UserCog, { className: "w-5 h-5" }), title: t('profileAdmin.rolesTab'), children: t('profileAdmin.rolesDescription') }), jsx(RolesTab, { tenant: tenant })] })), hasPoliciesTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "policies", children: [jsx(TabDescription, { icon: jsx(ScrollText, { className: "w-5 h-5" }), title: t('profileAdmin.policiesTab'), children: t('profileAdmin.policiesDescription') }), jsx(PoliciesTab, { tenant: tenant })] })), hasTeamsTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "teams", children: [jsx(TabDescription, { icon: jsx(Shield, { className: "w-5 h-5" }), title: t('profileAdmin.teamsTab'), children: t('profileAdmin.teamsDescription') }), jsx(GroupsTab, { tenant: tenant, isTeam: true, onInviteClick: onInviteClick, hasInviteUserPermission: hasInviteUserPermission, hasCreateTeamPermission: hasCreateTeamPermission, onLoadGroupPermissions: onLoadGroupPermissions, rbacPermissions: rbacPermissions, enableRbac: enableRbac })] })), hasAlertsTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "alerts", children: [jsx(TabDescription, { icon: jsx(BellRing, { className: "w-5 h-5" }), title: t('profileAdmin.alertsTab'), children: t('profileAdmin.alertsDescription') }), jsx(AlertsTab$1, { tenant: tenant })] })), jsxs(TabsContent, { className: "mt-4", value: "applications", children: [jsx(TabDescription, { icon: jsx(ClipboardList, { className: "w-5 h-5" }), title: t('profileAdmin.applicationsTab'), children: t('profileAdmin.applicationsTabDescription') }), jsx(ApplicationsTab, { platformKey: tenant, authSpaUrl: authSpaUrl })] }), jsxs(TabsContent, { className: "mt-4", value: "onboarding", children: [jsx(TabDescription, { icon: jsx(UserPlus, { className: "w-5 h-5" }), title: t('profileAdmin.onboardingTab'), children: t('profileAdmin.onboardingTabDescription') }), jsx(OnboardingTab, { platformKey: tenant, onboardingBasePath: onboardingBasePath })] })] }) }));
190616
190873
  };
190617
190874
 
190618
190875
  function DeleteApiModal({ isOpen, onClose, apiKey, tenantKey }) {
@@ -241253,14 +241510,18 @@ const onboardingSecondaryButtonClass = 'w-full text-center text-sm text-gray-500
241253
241510
  * the admin panel's Onboarding tab (tenant metadata
241254
241511
  * `user_onboarding_form`), rendered one step per section, with the answers
241255
241512
  * saved to the tenant metadata under `user_onboarding_submission[<username>]`
241256
- * and the form's agent — when it configures one — handed over on the last step
241257
- * through the embeddable `agent-ai` component.
241513
+ * and one of the form's agents — when it configures any — handed over on the
241514
+ * last step through the embeddable `agent-ai` component.
241515
+ *
241516
+ * Which agent that is comes from `agentId`, the id a host reads out of an
241517
+ * onboarding link like `/onboarding/<agent-id>`; without one the tenant's first
241518
+ * configured agent stands in.
241258
241519
  *
241259
241520
  * Reached through {@link OnboardingWizard} with `isAdminOnboarding={false}`;
241260
241521
  * the admin setup flow is a different component entirely.
241261
241522
  */
241262
- function UserOnboardingWizard({ tenant, username, onComplete, onResponsesSubmit, renderFinalStep, renderStepHeader, agentEmbed, form: formOverride, className, }) {
241263
- var _a, _b;
241523
+ function UserOnboardingWizard({ tenant, username, onComplete, onResponsesSubmit, renderFinalStep, renderStepHeader, agentEmbed, form: formOverride, agentId, className, }) {
241524
+ var _a;
241264
241525
  const t = useT();
241265
241526
  const { data, isLoading } = useGetTenantMetadataQuery([{ org: tenant }], {
241266
241527
  skip: !tenant || !!formOverride,
@@ -241281,16 +241542,23 @@ function UserOnboardingWizard({ tenant, username, onComplete, onResponsesSubmit,
241281
241542
  }, [seedKey]);
241282
241543
  /** Sections with something to ask, honouring their `visible_if`. */
241283
241544
  const steps = form.sections.filter((section) => { var _a, _b; return !section.repeatable && ((_b = (_a = section.fields) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0 && isVisible(section, responses); });
241284
- const agent = (_a = form.agent) !== null && _a !== void 0 ? _a : null;
241545
+ const agent = findOnboardingAgent(form, agentId);
241285
241546
  /** The last screen: the host's own, else the agent embed when configured. */
241286
241547
  const hasFinalStep = !!renderFinalStep || !!agent;
241287
241548
  const totalSteps = Math.max(steps.length + (hasFinalStep ? 1 : 0), 1);
241288
241549
  const onFinalStep = hasFinalStep && step >= steps.length;
241289
241550
  // An explicit `null` means "no agent" (nothing configured, or the flow ended
241290
- // before the agent step); only an omitted id falls back to the form's agent.
241291
- const complete = React.useCallback((agentId) => { var _a; return onComplete === null || onComplete === void 0 ? void 0 : onComplete(agentId === undefined ? ((_a = agent === null || agent === void 0 ? void 0 : agent.mentor_unique_id) !== null && _a !== void 0 ? _a : null) : agentId); }, [onComplete, agent]);
241292
- /** The tenant has set nothing up (or switched onboarding off). */
241293
- const nothingToShow = !isLoading && (!form.enabled || !hasOnboardingContent(form));
241551
+ // before the agent step); only an omitted id falls back to the resolved agent.
241552
+ // Named apart from the `agentId` prop, which chooses that agent rather than
241553
+ // reporting the one the user left on.
241554
+ const complete = React.useCallback((finishedWith) => { var _a; return onComplete === null || onComplete === void 0 ? void 0 : onComplete(finishedWith === undefined ? ((_a = agent === null || agent === void 0 ? void 0 : agent.mentor_unique_id) !== null && _a !== void 0 ? _a : null) : finishedWith); }, [onComplete, agent]);
241555
+ /**
241556
+ * Nothing to show: the tenant set nothing up (or switched onboarding off), or
241557
+ * the link names an agent this tenant does not onboard with and there are no
241558
+ * questions to fall back on. Either way the user is told, not left staring.
241559
+ */
241560
+ const nothingToShow = !isLoading &&
241561
+ (!form.enabled || !hasOnboardingContent(form) || (steps.length === 0 && !agent));
241294
241562
  /**
241295
241563
  * Render a step's heading: the host's way when it supplies one (the LMS puts
241296
241564
  * it in the navbar), otherwise the built-in centered header.
@@ -241422,7 +241690,7 @@ function UserOnboardingWizard({ tenant, username, onComplete, onResponsesSubmit,
241422
241690
  const section = steps[step];
241423
241691
  if (!section)
241424
241692
  return null;
241425
- const answers = (_b = responses[section.key]) !== null && _b !== void 0 ? _b : {};
241693
+ const answers = (_a = responses[section.key]) !== null && _a !== void 0 ? _a : {};
241426
241694
  return (jsx(OnboardingShell, { totalSteps: totalSteps, currentStep: step + 1, contentClassName: className, children: jsxs("div", { children: [stepHeader({
241427
241695
  icon: step === 0 ? ClipboardList : undefined,
241428
241696
  title: section.title || form.title || t('onboardingUserOnboarding.defaultTitle'),
@@ -242834,5 +243102,5 @@ var trainOrDeleteModal = /*#__PURE__*/Object.freeze({
242834
243102
  TrainOrDeleteModal: TrainOrDeleteModal
242835
243103
  });
242836
243104
 
242837
- export { ACCESS_COURSE_LABEL, ALL_CATEGORIES, AccessTimeHeatmap, AccessiblePaginate, AddMentorToProjectModal, AddSkillDialog, Admin, AdvancedTab, AgentConfigPrompts, AgentSkills, AlertsTab, AnalyticsAgentPicker, AnalyticsAuditLogStats, AnalyticsCourseDetail, AnalyticsCourses, AnalyticsFinancialStats, AnalyticsLayout, AnalyticsMemoryStats, AnalyticsMonetizationStats, AnalyticsOverview, AnalyticsPlatformAuditLog, AnalyticsProgramDetail, AnalyticsPrograms, AnalyticsReportDownload, AnalyticsReports, AnalyticsScopeProvider, AnalyticsSettingsProvider, AnalyticsTopicsStats, AnalyticsTranscriptsStats, AnalyticsUsersStats, AppleRestrictionModal, ApplyWizard, AuditLogChangesView, AuditLogJsonView, BUY_NOW_LABEL, BillingTab, CATALOGS, CREATE_AGENT_LABELS, CUA_DRIVER_REPO_URL, CUA_DRIVER_TAURI_COMMANDS, CUA_DRIVER_TAURI_EVENTS, CardInfoIcon, CategorizedDropdownMenu, ChartCardWrapper, ChartFiltersProvider, ChartLoading, ChatContext, ChatPrivacyToggle, ChatProvider, CompanyDialog, ConnectorManagementDialog, CopyButtonIcon, CourseAccessGuard, CourseCardSkeleton, CourseContentLoading, CourseOutline, CourseOutlineContext, CourseOutlineDrawer, CreateAgentForm, CreateAgentModal, CreateProjectModal, CreateWorkflowModal, CredentialBox, CredentialMiniBoxSkeleton, CredentialsList, CreditBalance, CustomDateRangePicker, CustomTooltip, DEFAULT_COWORK_REQUIRED_SIZE_GB, DEFAULT_LOCALE, DefaultEmptyBox, DeleteProjectModal, DeleteWorkflowModal, DiscoverContentCard, DiscoverFacetsFilter, DiscoverFilterDrawer, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, ENROLL_NOW_COURSE_STARTING_SOON_LABEL, ENROLL_NOW_LABEL, EditAlertDialog, EducationBox, EducationDialog, EducationTab, EdxIframeContext, EmptyStats, ExperienceBox, ExperienceDialog, ExperienceTab, FacetFilterContext, Footer, GradebookTab, GroupsFilterDropdown, INVITATION_ONLY_LABEL, InstitutionDialog, IntegrationsTab, InviteUserContent, InviteUserDialog, InvitedUsersDialog, LOCAL_MODELS, Loader, LocalLLMTab, LocalModelsContent, LoginButton, MACOS_PERMISSIONS_COMMANDS, MEMORY_PAGE_SIZE, Markdown, MinimumMentorAlert, MonetizationTab, NotificationDisplay, NotificationDropdown, ONBOARDING_FIELD_TYPES, ONBOARDING_SECTORS, OnboardingField, OnboardingShell, OnboardingWizard, PLATFORM_AUDIT_DEEP_PAGING_THRESHOLD, PLATFORM_AUDIT_PAGE_SIZE, PaywallModal, PlacementExam, PlacementExamsDropdown, PlatformAuditLogDetailSheet, PlatformNavbar, PlatformNavbarSearch, Profile, ProfileTimeChart, ProgressDots, ProjectActionButtons, ProjectFilesModal, ProjectInstructionsModal, ProjectLandingPage, ProjectMentorsList, ProjectsPage, REQUEST_ACCESS_COURSE_STARTING_SOON_LABEL, REQUEST_ACCESS_LABEL, RenameProjectModal, ResumeBox, ResumeTab, RichTextEditor, SUPPORTED_LOCALES, SandboxConfig, SearchableMultiSelect, SendNotificationDialog, SignupButton, SkeletonActivityStatBox, SkeletonAddSkillsLoading, SkeletonCreatePathwaySearchList, SkeletonDiscoverFilterBox, SkeletonEducationBox, SkeletonMultiplier, SkeletonPathwayBox, SkeletonProfileInfoCard, SkeletonSkillBox, SkillBox, SkillDetailModal, SkillLeaderboardChart, SkillsBox, SkillsList, SlashSkillPicker, Spinner, StatCard, StepHeader, SummerNoteTextEditor, TAURI_COMMANDS, TAURI_EVENTS, TenantSwitcher, TimeFilter, TimeTrackingProvider, TimedExam, ToolDialogs, TopBanner, USER_ONBOARDING_FORM_SLUG, USER_ONBOARDING_FORM_VERSION, USER_ONBOARDING_SUBMISSION_SLUG, UpgradePackageModal, UserAvatar, UserOnboardingWizard, Version, WebContainersI18nProvider, WorkflowSidebar, addBookmarksTab, availablePlacementExams, buildUserOnboardingFormMetadata, buildUserOnboardingSubmissionMetadata, coerceOnboardingAgent, coerceUserOnboardingForm, emptyUserOnboardingForm, findLastResumeBlock, findSequentialParent, flattenVerticalBlocks, formatAuditTimestamp, formatTimeZoneLabel, getCatalog, getFirstAvailableUnit, getLocalLLMModel, getLocalLLMToolSupport, getNextUnitIframe, getOrg, getParentBlockById, getParentsInfosFromSublessonId, getPreviousUnitIframe, getRandomCourseImage, getSectorById, getTenant, getUnitToIframe, getUserId, getUserName, hasOnboardingContent, humanizeAuditToken, inBrowserPrint, inIframe, initialCuaDriverInstallState, initialModelDownloadState, isCoworkEnabled, isLocalLLMEnabled, isPlatformNavbarCreditBalanceVisible, isSlashCommandToken, isTauriApp, isValidLocale, isValidTimeZone, components as markdownComponents, modelSupportsCowork, onboardingPrimaryButtonClass, onboardingSecondaryButtonClass, readUserOnboardingForm, readUserOnboardingSubmission, readUserOnboardingSubmissions, resolveAuditTimeZone, resolveCreateAgentLabels, sanitizeCss, setCoworkEnabled, setLocalLLMEnabled, setLocalLLMModel, setLocalLLMToolSupport, smallestCoworkModel, useAnalyticsScope, useAnalyticsSettings, useAuditLog, useCatalogSearch, useChartFilters, useChatPrivacy, useChatState, useCourseDetail, useCourseMetadata, useCourses, useCuaDriver, useDiscover, useEdxIframe, useFinancial, useIframeMessageHandler, useLocalStorage, useMemory, useModelDownload, useMonetization, useOverview, usePlatformAuditLabels, usePlatformAuditLog, useProfileActivityStats, useProfileCredentials, useProfilePathways, useProfilePrograms, useProfileSkills, useProfileTimeSpent, usePrograms, useReports, useScopedMentorDbId, useScopedMentorId, useSlashSkillPicker, useSlashSkills, useT, useTauri, useTimeTracking, useTopics, useTranscripts, useUserCourses, useUserMetadata, useUsers, useWebContainersI18n, useWebContainersLocale };
243105
+ export { ACCESS_COURSE_LABEL, ALL_CATEGORIES, AccessTimeHeatmap, AccessiblePaginate, AddMentorToProjectModal, AddSkillDialog, Admin, AdvancedTab, AgentConfigPrompts, AgentSkills, AlertsTab, AnalyticsAgentPicker, AnalyticsAuditLogStats, AnalyticsCourseDetail, AnalyticsCourses, AnalyticsFinancialStats, AnalyticsLayout, AnalyticsMemoryStats, AnalyticsMonetizationStats, AnalyticsOverview, AnalyticsPlatformAuditLog, AnalyticsProgramDetail, AnalyticsPrograms, AnalyticsReportDownload, AnalyticsReports, AnalyticsScopeProvider, AnalyticsSettingsProvider, AnalyticsTopicsStats, AnalyticsTranscriptsStats, AnalyticsUsersStats, AppleRestrictionModal, ApplyWizard, AuditLogChangesView, AuditLogJsonView, BUY_NOW_LABEL, BillingTab, CATALOGS, CREATE_AGENT_LABELS, CUA_DRIVER_REPO_URL, CUA_DRIVER_TAURI_COMMANDS, CUA_DRIVER_TAURI_EVENTS, CardInfoIcon, CategorizedDropdownMenu, ChartCardWrapper, ChartFiltersProvider, ChartLoading, ChatContext, ChatPrivacyToggle, ChatProvider, CompanyDialog, ConnectorManagementDialog, CopyButtonIcon, CourseAccessGuard, CourseCardSkeleton, CourseContentLoading, CourseOutline, CourseOutlineContext, CourseOutlineDrawer, CreateAgentForm, CreateAgentModal, CreateProjectModal, CreateWorkflowModal, CredentialBox, CredentialMiniBoxSkeleton, CredentialsList, CreditBalance, CustomDateRangePicker, CustomTooltip, DEFAULT_COWORK_REQUIRED_SIZE_GB, DEFAULT_LOCALE, DefaultEmptyBox, DeleteProjectModal, DeleteWorkflowModal, DiscoverContentCard, DiscoverFacetsFilter, DiscoverFilterDrawer, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, ENROLL_NOW_COURSE_STARTING_SOON_LABEL, ENROLL_NOW_LABEL, EditAlertDialog, EducationBox, EducationDialog, EducationTab, EdxIframeContext, EmptyStats, ExperienceBox, ExperienceDialog, ExperienceTab, FacetFilterContext, Footer, GradebookTab, GroupsFilterDropdown, INVITATION_ONLY_LABEL, InstitutionDialog, IntegrationsTab, InviteUserContent, InviteUserDialog, InvitedUsersDialog, LOCAL_MODELS, Loader, LocalLLMTab, LocalModelsContent, LoginButton, MACOS_PERMISSIONS_COMMANDS, MEMORY_PAGE_SIZE, Markdown, MinimumMentorAlert, MonetizationTab, NotificationDisplay, NotificationDropdown, ONBOARDING_FIELD_TYPES, ONBOARDING_SECTORS, OnboardingField, OnboardingShell, OnboardingWizard, PLATFORM_AUDIT_DEEP_PAGING_THRESHOLD, PLATFORM_AUDIT_PAGE_SIZE, PaywallModal, PlacementExam, PlacementExamsDropdown, PlatformAuditLogDetailSheet, PlatformNavbar, PlatformNavbarSearch, Profile, ProfileTimeChart, ProgressDots, ProjectActionButtons, ProjectFilesModal, ProjectInstructionsModal, ProjectLandingPage, ProjectMentorsList, ProjectsPage, REQUEST_ACCESS_COURSE_STARTING_SOON_LABEL, REQUEST_ACCESS_LABEL, RenameProjectModal, ResumeBox, ResumeTab, RichTextEditor, SUPPORTED_LOCALES, SandboxConfig, SearchableMultiSelect, SendNotificationDialog, SignupButton, SkeletonActivityStatBox, SkeletonAddSkillsLoading, SkeletonCreatePathwaySearchList, SkeletonDiscoverFilterBox, SkeletonEducationBox, SkeletonMultiplier, SkeletonPathwayBox, SkeletonProfileInfoCard, SkeletonSkillBox, SkillBox, SkillDetailModal, SkillLeaderboardChart, SkillsBox, SkillsList, SlashSkillPicker, Spinner, StatCard, StepHeader, SummerNoteTextEditor, TAURI_COMMANDS, TAURI_EVENTS, TenantSwitcher, TimeFilter, TimeTrackingProvider, TimedExam, ToolDialogs, TopBanner, USER_ONBOARDING_FORM_SLUG, USER_ONBOARDING_FORM_VERSION, USER_ONBOARDING_SUBMISSION_SLUG, UpgradePackageModal, UserAvatar, UserOnboardingWizard, Version, WebContainersI18nProvider, WorkflowSidebar, addBookmarksTab, availablePlacementExams, buildOnboardingAgentPath, buildUserOnboardingFormMetadata, buildUserOnboardingSubmissionMetadata, coerceOnboardingAgent, coerceOnboardingAgents, coerceUserOnboardingForm, emptyUserOnboardingForm, findLastResumeBlock, findOnboardingAgent, findSequentialParent, flattenVerticalBlocks, formatAuditTimestamp, formatTimeZoneLabel, getCatalog, getFirstAvailableUnit, getLocalLLMModel, getLocalLLMToolSupport, getNextUnitIframe, getOrg, getParentBlockById, getParentsInfosFromSublessonId, getPreviousUnitIframe, getRandomCourseImage, getSectorById, getTenant, getUnitToIframe, getUserId, getUserName, hasOnboardingContent, humanizeAuditToken, inBrowserPrint, inIframe, initialCuaDriverInstallState, initialModelDownloadState, isCoworkEnabled, isLocalLLMEnabled, isPlatformNavbarCreditBalanceVisible, isSlashCommandToken, isTauriApp, isValidLocale, isValidTimeZone, components as markdownComponents, modelSupportsCowork, onboardingPrimaryButtonClass, onboardingSecondaryButtonClass, readUserOnboardingForm, readUserOnboardingSubmission, readUserOnboardingSubmissions, resolveAuditTimeZone, resolveCreateAgentLabels, sanitizeCss, setCoworkEnabled, setLocalLLMEnabled, setLocalLLMModel, setLocalLLMToolSupport, smallestCoworkModel, useAnalyticsScope, useAnalyticsSettings, useAuditLog, useCatalogSearch, useChartFilters, useChatPrivacy, useChatState, useCourseDetail, useCourseMetadata, useCourses, useCuaDriver, useDiscover, useEdxIframe, useFinancial, useIframeMessageHandler, useLocalStorage, useMemory, useModelDownload, useMonetization, useOverview, usePlatformAuditLabels, usePlatformAuditLog, useProfileActivityStats, useProfileCredentials, useProfilePathways, useProfilePrograms, useProfileSkills, useProfileTimeSpent, usePrograms, useReports, useScopedMentorDbId, useScopedMentorId, useSlashSkillPicker, useSlashSkills, useT, useTauri, useTimeTracking, useTopics, useTranscripts, useUserCourses, useUserMetadata, useUsers, useWebContainersI18n, useWebContainersLocale };
242838
243106
  //# sourceMappingURL=index.esm.js.map