@arbidocs/blocks 0.5.23 → 0.5.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/dist/{ConnectedNativeDocxComparison-GMQHSY3Z.js → ConnectedNativeDocxComparison-MZX222GC.js} +6 -6
  2. package/dist/{ConnectedNativeDocxComparison-GMQHSY3Z.js.map → ConnectedNativeDocxComparison-MZX222GC.js.map} +1 -1
  3. package/dist/{ConnectedNativeDocxComparison-HH3PHNXU.cjs → ConnectedNativeDocxComparison-WRO3J6VV.cjs} +7 -7
  4. package/dist/{ConnectedNativeDocxComparison-HH3PHNXU.cjs.map → ConnectedNativeDocxComparison-WRO3J6VV.cjs.map} +1 -1
  5. package/dist/{ConnectedNativeDocxEditor-4IAKVBEF.js → ConnectedNativeDocxEditor-OJ6SYZ3W.js} +5 -5
  6. package/dist/{ConnectedNativeDocxEditor-4IAKVBEF.js.map → ConnectedNativeDocxEditor-OJ6SYZ3W.js.map} +1 -1
  7. package/dist/{ConnectedNativeDocxEditor-JNHNZG3P.cjs → ConnectedNativeDocxEditor-XTUJWL25.cjs} +7 -7
  8. package/dist/{ConnectedNativeDocxEditor-JNHNZG3P.cjs.map → ConnectedNativeDocxEditor-XTUJWL25.cjs.map} +1 -1
  9. package/dist/{ConnectedStreamedWordArtifact-CZZOH667.cjs → ConnectedStreamedWordArtifact-5JURNV4L.cjs} +7 -7
  10. package/dist/ConnectedStreamedWordArtifact-5JURNV4L.cjs.map +1 -0
  11. package/dist/{ConnectedStreamedWordArtifact-GLJCJPTP.js → ConnectedStreamedWordArtifact-KURJRZH3.js} +6 -6
  12. package/dist/{ConnectedStreamedWordArtifact-GLJCJPTP.js.map → ConnectedStreamedWordArtifact-KURJRZH3.js.map} +1 -1
  13. package/dist/{WorkspaceTableView-ECPHGWHF.js → WorkspaceTableView-2XI6FIOO.js} +7 -7
  14. package/dist/WorkspaceTableView-2XI6FIOO.js.map +1 -0
  15. package/dist/{WorkspaceTableView-6JVHGDUB.cjs → WorkspaceTableView-KG4D53SK.cjs} +13 -13
  16. package/dist/WorkspaceTableView-KG4D53SK.cjs.map +1 -0
  17. package/dist/agents/index.cjs +326 -326
  18. package/dist/agents/index.js +4 -4
  19. package/dist/{chunk-X4Y7ZHFB.js → chunk-2GDKBLD5.js} +11 -6
  20. package/dist/chunk-2GDKBLD5.js.map +1 -0
  21. package/dist/{chunk-DXO2RXVQ.cjs → chunk-3FQHFFV5.cjs} +4 -4
  22. package/dist/{chunk-DXO2RXVQ.cjs.map → chunk-3FQHFFV5.cjs.map} +1 -1
  23. package/dist/{chunk-AAVFCPKD.js → chunk-3OATYBZK.js} +4 -4
  24. package/dist/{chunk-AAVFCPKD.js.map → chunk-3OATYBZK.js.map} +1 -1
  25. package/dist/{chunk-AF24CV6J.js → chunk-4I2V55LL.js} +3 -3
  26. package/dist/{chunk-AF24CV6J.js.map → chunk-4I2V55LL.js.map} +1 -1
  27. package/dist/{chunk-VNHLFS6T.cjs → chunk-4KLBM5K5.cjs} +4 -4
  28. package/dist/{chunk-VNHLFS6T.cjs.map → chunk-4KLBM5K5.cjs.map} +1 -1
  29. package/dist/{chunk-7DDMF3DZ.cjs → chunk-53T2FY4Z.cjs} +5 -31
  30. package/dist/chunk-53T2FY4Z.cjs.map +1 -0
  31. package/dist/{chunk-BTF4AZMG.js → chunk-57CG33XJ.js} +5 -5
  32. package/dist/chunk-57CG33XJ.js.map +1 -0
  33. package/dist/chunk-5ZBXFHZW.js +434 -0
  34. package/dist/chunk-5ZBXFHZW.js.map +1 -0
  35. package/dist/{chunk-KJVDYWAM.cjs → chunk-6UKNYQ7Q.cjs} +13 -8
  36. package/dist/chunk-6UKNYQ7Q.cjs.map +1 -0
  37. package/dist/{chunk-TTJGCJWX.cjs → chunk-6UZ6YTML.cjs} +46 -6
  38. package/dist/chunk-6UZ6YTML.cjs.map +1 -0
  39. package/dist/{chunk-NVRJ6WTR.js → chunk-7RFDYAK7.js} +3 -3
  40. package/dist/{chunk-NVRJ6WTR.js.map → chunk-7RFDYAK7.js.map} +1 -1
  41. package/dist/{chunk-ZYGQFD5Y.js → chunk-BSDZXG55.js} +3 -3
  42. package/dist/{chunk-ZYGQFD5Y.js.map → chunk-BSDZXG55.js.map} +1 -1
  43. package/dist/{chunk-O4EQYPLO.cjs → chunk-C2SZQKX2.cjs} +169 -27
  44. package/dist/chunk-C2SZQKX2.cjs.map +1 -0
  45. package/dist/{chunk-I5RK4WAE.cjs → chunk-FGZQUH2Y.cjs} +3 -3
  46. package/dist/{chunk-I5RK4WAE.cjs.map → chunk-FGZQUH2Y.cjs.map} +1 -1
  47. package/dist/{chunk-7S76Q5RK.js → chunk-GA2A7OX6.js} +3 -3
  48. package/dist/{chunk-7S76Q5RK.js.map → chunk-GA2A7OX6.js.map} +1 -1
  49. package/dist/{chunk-XL55UDLO.js → chunk-IJJKUTKM.js} +5 -30
  50. package/dist/chunk-IJJKUTKM.js.map +1 -0
  51. package/dist/{chunk-BL74GYSA.cjs → chunk-JGCYM3II.cjs} +9 -9
  52. package/dist/{chunk-BL74GYSA.cjs.map → chunk-JGCYM3II.cjs.map} +1 -1
  53. package/dist/{chunk-ZX663X3X.cjs → chunk-KNRAKOCO.cjs} +6 -428
  54. package/dist/chunk-KNRAKOCO.cjs.map +1 -0
  55. package/dist/chunk-KUQOHPKP.cjs +443 -0
  56. package/dist/chunk-KUQOHPKP.cjs.map +1 -0
  57. package/dist/{chunk-JUUOJP7I.cjs → chunk-KWJW5TMH.cjs} +5 -5
  58. package/dist/chunk-KWJW5TMH.cjs.map +1 -0
  59. package/dist/{chunk-FZVAJFRH.cjs → chunk-LAGHW4JM.cjs} +24 -10
  60. package/dist/chunk-LAGHW4JM.cjs.map +1 -0
  61. package/dist/{chunk-6XW3CMU4.js → chunk-N3KNAQ55.js} +144 -4
  62. package/dist/chunk-N3KNAQ55.js.map +1 -0
  63. package/dist/{chunk-C6P2QW36.js → chunk-NZIVQ4Q4.js} +4 -4
  64. package/dist/{chunk-C6P2QW36.js.map → chunk-NZIVQ4Q4.js.map} +1 -1
  65. package/dist/{chunk-44FPFTU2.js → chunk-ORUV4MEP.js} +3 -3
  66. package/dist/{chunk-44FPFTU2.js.map → chunk-ORUV4MEP.js.map} +1 -1
  67. package/dist/{chunk-75Z5AUMM.js → chunk-QB6JCNVG.js} +3 -3
  68. package/dist/{chunk-75Z5AUMM.js.map → chunk-QB6JCNVG.js.map} +1 -1
  69. package/dist/{chunk-S4G3DNMA.cjs → chunk-QZTA2M4U.cjs} +9 -9
  70. package/dist/{chunk-S4G3DNMA.cjs.map → chunk-QZTA2M4U.cjs.map} +1 -1
  71. package/dist/{chunk-F2BYURQZ.cjs → chunk-T67EFI43.cjs} +5 -5
  72. package/dist/{chunk-F2BYURQZ.cjs.map → chunk-T67EFI43.cjs.map} +1 -1
  73. package/dist/{chunk-RVKVGS72.js → chunk-TDFL676I.js} +25 -11
  74. package/dist/chunk-TDFL676I.js.map +1 -0
  75. package/dist/{chunk-YD3RN2FY.cjs → chunk-U72QI2W3.cjs} +3 -3
  76. package/dist/{chunk-YD3RN2FY.cjs.map → chunk-U72QI2W3.cjs.map} +1 -1
  77. package/dist/{chunk-75UVQKQ5.cjs → chunk-WTGJHS7F.cjs} +48 -48
  78. package/dist/{chunk-75UVQKQ5.cjs.map → chunk-WTGJHS7F.cjs.map} +1 -1
  79. package/dist/{chunk-SLRVI2YU.js → chunk-X6U6L6BG.js} +29 -4
  80. package/dist/chunk-X6U6L6BG.js.map +1 -0
  81. package/dist/{chunk-SQ5F5BFW.cjs → chunk-XDU3HHUU.cjs} +32 -6
  82. package/dist/chunk-XDU3HHUU.cjs.map +1 -0
  83. package/dist/{chunk-SKVVOEMX.js → chunk-XXUPUXBF.js} +8 -423
  84. package/dist/chunk-XXUPUXBF.js.map +1 -0
  85. package/dist/{chunk-PZRTRYPD.js → chunk-ZKAIT3M2.js} +46 -7
  86. package/dist/chunk-ZKAIT3M2.js.map +1 -0
  87. package/dist/connect/docx.cjs +9 -9
  88. package/dist/connect/docx.js +5 -5
  89. package/dist/connect/index.cjs +1393 -891
  90. package/dist/connect/index.cjs.map +1 -1
  91. package/dist/connect/index.js +739 -242
  92. package/dist/connect/index.js.map +1 -1
  93. package/dist/connect/viewer.cjs +4 -4
  94. package/dist/connect/viewer.js +4 -4
  95. package/dist/connection/auth/CompactLogin.d.ts +26 -0
  96. package/dist/connection/auth/ConnectedLoginPage.d.ts +9 -1
  97. package/dist/connection/auth/index.d.ts +3 -1
  98. package/dist/connection/auth/sso-popup.d.ts +13 -0
  99. package/dist/connection/auth/sso-sign-in.d.ts +38 -0
  100. package/dist/connection/auth/useLoginActions.d.ts +4 -2
  101. package/dist/connection/projects/ConnectedProjectsPanel.d.ts +9 -1
  102. package/dist/connection/projects/ProjectsListPage.d.ts +41 -0
  103. package/dist/connection/projects/index.d.ts +1 -0
  104. package/dist/connection/settings-page/appearanceSection.d.ts +30 -0
  105. package/dist/connection/settings-page/index.d.ts +1 -0
  106. package/dist/facts/index.cjs +55 -55
  107. package/dist/facts/index.js +3 -3
  108. package/dist/index.cjs +498 -526
  109. package/dist/index.cjs.map +1 -1
  110. package/dist/index.d.ts +2 -0
  111. package/dist/index.js +15 -54
  112. package/dist/index.js.map +1 -1
  113. package/dist/settings/AppearanceSettings.d.ts +1 -2
  114. package/dist/settings/index.cjs +162 -162
  115. package/dist/settings/index.d.ts +2 -1
  116. package/dist/settings/index.js +2 -2
  117. package/dist/site/index.cjs +82 -74
  118. package/dist/site/index.d.ts +2 -0
  119. package/dist/site/index.js +3 -3
  120. package/dist/studio/index.cjs +73 -73
  121. package/dist/studio/index.js +5 -5
  122. package/dist/theme/appearance.d.ts +47 -0
  123. package/dist/theme/fromCss.d.ts +33 -0
  124. package/dist/workflow-canvas/index.cjs +20 -18
  125. package/dist/workflow-canvas/index.cjs.map +1 -1
  126. package/dist/workflow-canvas/index.js +8 -6
  127. package/dist/workflow-canvas/index.js.map +1 -1
  128. package/dist/workspaces/index.cjs +43 -43
  129. package/dist/workspaces/index.js +3 -3
  130. package/node_modules/@arbidocs/coedit/package.json +1 -1
  131. package/package.json +5 -5
  132. package/dist/ConnectedStreamedWordArtifact-CZZOH667.cjs.map +0 -1
  133. package/dist/WorkspaceTableView-6JVHGDUB.cjs.map +0 -1
  134. package/dist/WorkspaceTableView-ECPHGWHF.js.map +0 -1
  135. package/dist/chunk-6XW3CMU4.js.map +0 -1
  136. package/dist/chunk-7DDMF3DZ.cjs.map +0 -1
  137. package/dist/chunk-AMTWY22T.js +0 -11
  138. package/dist/chunk-AMTWY22T.js.map +0 -1
  139. package/dist/chunk-BTF4AZMG.js.map +0 -1
  140. package/dist/chunk-FZVAJFRH.cjs.map +0 -1
  141. package/dist/chunk-JUUOJP7I.cjs.map +0 -1
  142. package/dist/chunk-KJVDYWAM.cjs.map +0 -1
  143. package/dist/chunk-O4EQYPLO.cjs.map +0 -1
  144. package/dist/chunk-PZRTRYPD.js.map +0 -1
  145. package/dist/chunk-RVKVGS72.js.map +0 -1
  146. package/dist/chunk-SKVVOEMX.js.map +0 -1
  147. package/dist/chunk-SLRVI2YU.js.map +0 -1
  148. package/dist/chunk-SQ5F5BFW.cjs.map +0 -1
  149. package/dist/chunk-TTJGCJWX.cjs.map +0 -1
  150. package/dist/chunk-X4Y7ZHFB.js.map +0 -1
  151. package/dist/chunk-XL55UDLO.js.map +0 -1
  152. package/dist/chunk-ZU2B2RZK.cjs +0 -13
  153. package/dist/chunk-ZU2B2RZK.cjs.map +0 -1
  154. package/dist/chunk-ZX663X3X.cjs.map +0 -1
@@ -1,17 +1,17 @@
1
1
  "use client";
2
- import { useBillingSupport, formatMoney, isProProject, useSelfExtId, addonCharge, formatPeriodEnd, quoteParts, taxDetail, money2, ANNUAL_PREMIUM_AI_NOTE, totalWithTaxWord, planBadgeView, DEFAULT_SPEND_CAP_PENCE, findProPrices, packPrice, calcSavingsPercent, parseBudgetPounds, isAddonBudgetZero, useRewardBalance, getQuotaItems, aiUsageResetTimestamp, formatResetDate, ZERO_BUDGET_MESSAGE, CAP_REACHED_MESSAGE, PRO_PACKS, planNameForPacks, proTierName, STORAGE_BLOCK_GB, ADDON_BLOCK_AI_GBP, quoteError, POSTCODE_COUNTRIES, addonPrice, checkoutBlockPriceText, quoteTotalLine, apiErrorDetail, checkoutItemsLabel, projectGroupBilling, SUGGESTED_DAILY_CAP_PER_USER, FREE_STORAGE_MB, FREE_AI_GBP, PRO_AI_GBP, PRO_STORAGE_GB, plusVat, planPreviewLines, PAY_TODAY_UNPRICED, TAX_LOCATION_INVALID, FREE_COLLABORATORS, MAX_CHECKOUT_BLOCKS, reduceBounds, splitBlocks, autoRoom, nextRemovedBlockSize, stepLabel, addStepCaption, blocksLabel, MIN_AUTO_TOPUP_THRESHOLD_GBP, USAGE_CAP_LABEL, USAGE_CAP_HELP, PLAN_CHOICE_PACKS, nextPeriodBody, addonSettingsBody, budgetSavedMessage } from '../chunk-NVRJ6WTR.js';
3
- export { CAP_REACHED_MESSAGE, ZERO_BUDGET_MESSAGE, aiUsageResetTimestamp, formatMoney, formatResetDate, getQuotaItems, isAddonBudgetZero, isProProject, planBadgeView, planName, projectGroupBilling, useBillingSupport, useRewardBalance } from '../chunk-NVRJ6WTR.js';
4
- import { getRoleBadgeClass, formatRole, getRoleDescription, PageLoading, WorkspacePageFrame, WorkspaceIdentityPanel, WorkspaceProjectSlot, WorkspaceAudienceLine, CommonWorkspaceToggle, ExpandableSection, LeaveFooter, ProjectPicker, WorkspaceTypeBadge, WorkspaceList, WorkspaceGroup, WorkspaceCard } from '../chunk-X4Y7ZHFB.js';
5
- import { isAgentAccount, workspaceConversationCount, workspaceDocumentCount, isListedWorkspace, WORKSPACE_CATEGORY_FILTERS, projectFilterId, workspaceFilterAttributes, groupWorkspacesByProject, workspaceGroupStats, byRecentUpdate } from '../chunk-BTF4AZMG.js';
2
+ import { useBillingSupport, formatMoney, isProProject, useSelfExtId, addonCharge, formatPeriodEnd, quoteParts, taxDetail, money2, ANNUAL_PREMIUM_AI_NOTE, totalWithTaxWord, planBadgeView, DEFAULT_SPEND_CAP_PENCE, findProPrices, packPrice, calcSavingsPercent, parseBudgetPounds, isAddonBudgetZero, useRewardBalance, getQuotaItems, aiUsageResetTimestamp, formatResetDate, ZERO_BUDGET_MESSAGE, CAP_REACHED_MESSAGE, PRO_PACKS, planNameForPacks, proTierName, STORAGE_BLOCK_GB, ADDON_BLOCK_AI_GBP, quoteError, POSTCODE_COUNTRIES, addonPrice, checkoutBlockPriceText, quoteTotalLine, apiErrorDetail, checkoutItemsLabel, projectGroupBilling, SUGGESTED_DAILY_CAP_PER_USER, FREE_STORAGE_MB, FREE_AI_GBP, PRO_AI_GBP, PRO_STORAGE_GB, plusVat, planPreviewLines, PAY_TODAY_UNPRICED, TAX_LOCATION_INVALID, FREE_COLLABORATORS, MAX_CHECKOUT_BLOCKS, reduceBounds, splitBlocks, autoRoom, nextRemovedBlockSize, stepLabel, addStepCaption, blocksLabel, MIN_AUTO_TOPUP_THRESHOLD_GBP, USAGE_CAP_LABEL, USAGE_CAP_HELP, PLAN_CHOICE_PACKS, nextPeriodBody, addonSettingsBody, budgetSavedMessage } from '../chunk-7RFDYAK7.js';
3
+ export { CAP_REACHED_MESSAGE, ZERO_BUDGET_MESSAGE, aiUsageResetTimestamp, formatMoney, formatResetDate, getQuotaItems, isAddonBudgetZero, isProProject, planBadgeView, planName, projectGroupBilling, useBillingSupport, useRewardBalance } from '../chunk-7RFDYAK7.js';
4
+ import { getRoleBadgeClass, formatRole, getRoleDescription, PageLoading, WorkspacePageFrame, WorkspaceIdentityPanel, WorkspaceProjectSlot, WorkspaceAudienceLine, CommonWorkspaceToggle, ExpandableSection, LeaveFooter, ProjectPicker, WorkspaceTypeBadge, WorkspaceList, WorkspaceGroup, WorkspaceCard } from '../chunk-2GDKBLD5.js';
5
+ import { isAgentAccount, workspaceConversationCount, workspaceDocumentCount, isListedWorkspace, WORKSPACE_CATEGORY_FILTERS, projectFilterId, workspaceFilterAttributes, groupWorkspacesByProject, workspaceGroupStats, byRecentUpdate } from '../chunk-57CG33XJ.js';
6
6
  import { SharedFileView, SharedFilesInbox } from '../chunk-4ML5AMMO.js';
7
- import { buildFactCitations, citedVersionRef, chronologyFactBodies, docIdsOf, toFactCitations, FactsToolbar, FactsFieldsButton, FactComposer, FactDateInput, FactSourcesRow, FactsLoading, FactsLoadError, FactsEmptyState, FactsCalendar, FactsGanttPane, FactsBulkBar, FactSourceGroup, EMPTY_FACT_DATE_FIELDS, withoutChunk, factDateSpanToFields, FactFieldRow, FactLabelsCell, enableFactTableColumnResize, withChunk, factDateFieldsToSpan, createFactColumns, FactRowActions, withoutDoc, withDoc, sourceDocCount, DEFAULT_FACT_COLUMN_LABELS } from '../chunk-75Z5AUMM.js';
7
+ import { buildFactCitations, citedVersionRef, chronologyFactBodies, docIdsOf, toFactCitations, FactsToolbar, FactsFieldsButton, FactComposer, FactDateInput, FactSourcesRow, FactsLoading, FactsLoadError, FactsEmptyState, FactsCalendar, FactsGanttPane, FactsBulkBar, FactSourceGroup, EMPTY_FACT_DATE_FIELDS, withoutChunk, factDateSpanToFields, FactFieldRow, FactLabelsCell, enableFactTableColumnResize, withChunk, factDateFieldsToSpan, createFactColumns, FactRowActions, withoutDoc, withDoc, sourceDocCount, DEFAULT_FACT_COLUMN_LABELS } from '../chunk-QB6JCNVG.js';
8
8
  import { HomeLoadError, HomeFrame, HomeMain, HomeCenteredScroll, HomeCenteredColumn, DashboardRoot, DashboardBand, DashboardColumns, RecentList, DashboardAction, FactsStrip, FactMark, CreateTile } from '../chunk-IKTPM73F.js';
9
9
  import { ProjectBandTitle, PlainBandTitle } from '../chunk-RQKWYKZY.js';
10
10
  import '../chunk-WZ63HE2C.js';
11
- import { MessageJsonTree, DraggableHeader, ProfileCard, AvatarPicker, IdentityVerificationCard, IdentityVerificationDialog, RequireVerified, PasswordChangeDialog, EMAIL_NOTIFICATION_KEYS, EMAIL_NOTIFICATION_CATEGORIES, NotificationCategoryList, toNotificationCategories, toActiveSessionViews, ActiveSessionsDialog, LogoutDialog, toLogoutSessionViews, DeleteAccountDialog, toDeleteBlockerViews, PremiumModelsFrame, ConnectionsLoading, ConnectionsError, ConnectionsEmpty, UsageToggle, SettingsPage, UsageSummary, UsageLineChart, SyncDialogBody, SyncField, SyncSelect, SyncSmallNote, SyncLoading, SyncReconnectNotice, SyncNote, SyncTreeFrame, SyncLinkRow, SyncLinkButton, SyncOptions, SyncOptionToggle, SyncDialogFooter, InvoicesDialog, PlanDialogFrame, ProjectList, RenameDialog, SharedProjectsSection, SharedProjectRow, MoreInfo, MoreInfoList, UsagePanel, UsageQuotaHint, UsageSection, UsageLegend, UsageProportionBar, UsageActionButton, ProjectDetailHeader, PlanBadge, ProjectDetailSection, PlanStack, PlanNotice, PlanPickerCard, PlanPickerHeader, PricingToggle, PromoCodeInput, PlanActionButton, QuotaExceededDialogView, InviteContactsDialog, WelcomeDialog, applyTriStateFilters, PanelFrame, PanelAddButton, PanelFrameBody, PanelScroll, PanelActionsRow, applyInvertedIndexFilter, ConfigSwitcherBar, PanelNote, ProjectRow, QuotaMeter, FilterChip, buildInvertedIndex, serverConnectionView, ServerConnectionButton, ModelProviderLabel, SyncFolderRow, SyncFolderStatus, PlanTierOption, PlanActionRow, SubscriptionStatusView, DailyCapField, PlanInfoPopover, PlanCardGrid, ReferralRewardSummary, CheckoutDialogFrame, ConnectionCard, ReferralRewardNote } from '../chunk-RVKVGS72.js';
11
+ import { MessageJsonTree, DraggableHeader, ProfileCard, AvatarPicker, IdentityVerificationCard, IdentityVerificationDialog, RequireVerified, PasswordChangeDialog, EMAIL_NOTIFICATION_KEYS, EMAIL_NOTIFICATION_CATEGORIES, NotificationCategoryList, toNotificationCategories, toActiveSessionViews, ActiveSessionsDialog, LogoutDialog, toLogoutSessionViews, DeleteAccountDialog, toDeleteBlockerViews, PremiumModelsFrame, ConnectionsLoading, ConnectionsError, ConnectionsEmpty, UsageToggle, SettingsPage, UsageSummary, AppearanceSettings, UsageLineChart, SyncDialogBody, SyncField, SyncSelect, SyncSmallNote, SyncLoading, SyncReconnectNotice, SyncNote, SyncTreeFrame, SyncLinkRow, SyncLinkButton, SyncOptions, SyncOptionToggle, SyncDialogFooter, InvoicesDialog, PlanDialogFrame, ProjectList, RenameDialog, SharedProjectsSection, SharedProjectRow, MoreInfo, MoreInfoList, UsagePanel, UsageQuotaHint, UsageSection, UsageLegend, UsageProportionBar, UsageActionButton, ProjectDetailHeader, PlanBadge, ProjectDetailSection, PlanStack, PlanNotice, PlanPickerCard, PlanPickerHeader, PricingToggle, PromoCodeInput, PlanActionButton, QuotaExceededDialogView, InviteContactsDialog, WelcomeDialog, applyTriStateFilters, PanelFrame, PanelAddButton, PanelFrameBody, PanelScroll, PanelActionsRow, applyInvertedIndexFilter, ConfigSwitcherBar, PanelNote, ProjectRow, QuotaMeter, FilterChip, buildInvertedIndex, serverConnectionView, ServerConnectionButton, ModelProviderLabel, SyncFolderRow, SyncFolderStatus, PlanTierOption, PlanActionRow, SubscriptionStatusView, DailyCapField, PlanInfoPopover, PlanCardGrid, ReferralRewardSummary, CheckoutDialogFrame, ConnectionCard, ReferralRewardNote } from '../chunk-TDFL676I.js';
12
12
  export { ConnectedAssistantDock, redlineStats, textToArtifact, toRedlineMarkdown, useConnectedAiTask, useConnectedChat, useSemanticSearch, useWorkspaceDocs } from '../chunk-MUF3RFJZ.js';
13
- import { useConnectedWorkspaceRole, useConnectedWorkflowScopeSource, ConnectedWorkflowDocumentsField, ConnectedWorkflowLauncher, ConnectedNativeDocxEditor, toWorkflowFieldDocument } from '../chunk-AAVFCPKD.js';
14
- export { ConnectedWorkflowDocumentsField, ConnectedWorkflowLauncher, ConnectedWorkflowsTable, DEFAULT_CONNECTED_WORKFLOWS_TABLE_LABELS, toWorkflowFieldDocument, useConnectedAgentOptions, useConnectedWorkflowScopeSource, useConnectedWorkspaceRole, useDocxCommentTarget, useNativeDocxSupport } from '../chunk-AAVFCPKD.js';
13
+ import { useConnectedWorkspaceRole, useConnectedWorkflowScopeSource, ConnectedWorkflowDocumentsField, ConnectedWorkflowLauncher, ConnectedNativeDocxEditor, toWorkflowFieldDocument } from '../chunk-3OATYBZK.js';
14
+ export { ConnectedWorkflowDocumentsField, ConnectedWorkflowLauncher, ConnectedWorkflowsTable, DEFAULT_CONNECTED_WORKFLOWS_TABLE_LABELS, toWorkflowFieldDocument, useConnectedAgentOptions, useConnectedWorkflowScopeSource, useConnectedWorkspaceRole, useDocxCommentTarget, useNativeDocxSupport } from '../chunk-3OATYBZK.js';
15
15
  import { ConnectedMarkdown, InternalDocLink, ExternalLink, DocumentWorkspaceContext } from '../chunk-M4FLTGFM.js';
16
16
  export { ConnectedDocumentToolsProvider, ConnectedMarkdown, DocumentChip, DocumentWorkspaceContext, ExternalLink, InternalDocLink, MailChip, MermaidDiagram, WorkspaceDocumentReference, useDocumentViewerSupport, useDocumentWorkspace, useViewerDraftDocument, useViewerIsDetached, useViewerPassageCitation, useViewerStreamingDocument } from '../chunk-M4FLTGFM.js';
17
17
  import { ExplorerFileTile, formatFolderSegment, hasFolderProviderIcon, FolderProviderIcon, ExplorerFolderTile, StatusPill, FailedStageIcon, DocumentNameCellFrame, DocumentRowMenu, visibilityToggleTooltip, FolderCell, FolderCommandList, RelatedDocsCell, FilterButton, DOCUMENTS_ROW_HEIGHT_INITIAL, searchExplorerDocuments, buildExplorerEntries, collectFolderDocs, joinFolderPath, getExplorerDisplayName, RECENTLY_DELETED_HINT, RECENTLY_DELETED_HINT_PLURAL, canDeleteDocument, ExplorerFrame, ExplorerStage, ExplorerScroller, ExplorerLoadingTiles, ExplorerEmpty, ExplorerMarquee, ExplorerDropOverlay, ExplorerDragPreview, CheckboxCell, TagColumnHeader, ExplorerFileTooltip, visibilityAudience, TagFormRoot, TagFormNameField, TagFormSelectField, TagFormNote, TagFormOptionsEditor, TagFormInstructionField, TagFormMeta, TagFormFooter, TagFormSharedToggle, FilesViewCenter, FilesFilterBar, TransferProgressView, TransferResumeBanner, ExportResultsReport, TransferScopeChooser, TransferKindsPicker, TransferReferencesChooser, ExportMethodChooser, ExportWorkspacePicker, TransferConflictChooser, TransferPlanSummary, ExportFooter, ExportModalTitle, ROW_MIN, rowHeightForLines, linesForRowHeight, RowDensityControl, VendorLogo, FolderFilterButton, FolderPickerRow, UploadFrame, UploadContainer, SelectedFilesList, RejectedFilesList, UploadErrorMessage, UploadProgress, PrivacyExplainerModal, MultiSelectCellEditor, DOCUMENT_TYPE_OPTIONS, DEFAULT_DOCUMENT_COLUMNS, shareStateOf, BulkActionsBar, shareTooltipFor, parseFolderSegments, AiReviewDialogView, MoveToFolderDialog, sortFields, filterFieldsByName, fieldsApplyBarCopy, FieldsEditorRoot, FieldsEditorToolbar, FieldsEditorList, FieldRow, FieldsEmptyState, fieldsEmptyText, FieldsApplyBar, FieldsManagerDefinition, FieldsManagerBody, FieldsManagerTitle, BulkTagEditorDialog, BulkReplaceDialog, FieldValue, FieldFolderSelect, FieldFolderValue, FieldNativeSelect, FieldWithAttribution, EMAIL_VIEW_COLUMNS, useGridViews, ViewSelectorMenu, FilesAddMenu, applyColumnLayout, applyViewColumns, sortExplorerFiles, FilesPage, UrlInputDialog, FilesPageHeader, FilesToolbar, ExplorerFileNavigator, NavigatorPickerBar, FilesPageMain, DocumentGrid, resolveDocumentGridLayout, FilesModalFooter, BulkLabelSelectView, confirmHideFromMembers, DocumentsFolderButton, FilesTagsButton, UploadSourceSection, UploadSourcePicker, UploadBrowseButtons, canEditDocumentFields, FieldLabelsSelect, ShareToggle, FieldAttribution, UploadDropArea, canChangeVisibility, UploadUrlButton } from '../chunk-XVGUR746.js';
@@ -24,13 +24,13 @@ import '../chunk-MTSKK3BN.js';
24
24
  import '../chunk-LU23I2HS.js';
25
25
  import { FactSourcesPanel, FactPassageItem } from '../chunk-HFZ45FD3.js';
26
26
  import '../chunk-IA5BYEO7.js';
27
- import { EntityTooltip, EntityTooltipHeader, EntityTooltipSection, EntityTooltipHint, SharedCell, WorkspaceActivityList, WorkspaceNotificationMenu, ThreadFollowMenuItem, ThreadFollowButton, TagTable, TagPicker, tagsPageNouns, entitiesPhrase, ExtractEntitiesDialog, GridRowNavigator, LoadingIndicator, EntityIdentityBar, IDENTITY_NAME_MAX_LENGTH, EntityTooltipStats, tagTableDocx, documentCount, tagTableLabels, TagDetail, tagDetailLabels, tagNoteLabel, tagKindDescription, glossaryEntries, glossaryDocx, glossaryMarkdown, glossaryFileName } from '../chunk-PZRTRYPD.js';
27
+ import { EntityTooltip, EntityTooltipHeader, EntityTooltipSection, EntityTooltipHint, SharedCell, WorkspaceActivityList, WorkspaceNotificationMenu, ThreadFollowMenuItem, ThreadFollowButton, TagTable, TagPicker, tagsPageNouns, entitiesPhrase, ExtractEntitiesDialog, GridRowNavigator, LoadingIndicator, EntityIdentityBar, IDENTITY_NAME_MAX_LENGTH, EntityTooltipStats, tagTableDocx, documentCount, tagTableLabels, TagDetail, tagDetailLabels, tagNoteLabel, tagKindDescription, Toolbar, glossaryEntries, glossaryDocx, glossaryMarkdown, glossaryFileName } from '../chunk-ZKAIT3M2.js';
28
28
  import { MemberAvatarStack } from '../chunk-FUPAGAZB.js';
29
29
  import { renderSearchSnippet, SearchGroupHeader, isMeaningMatch, extractHighlightTerms, passesRelevanceCutoff, groupSearchResults, SearchPillToggle, SearchPagination, SearchPageFrame, SearchPageHeader, ApplyLabelDialog, SearchPageBody, SearchToolbarRow, SearchBar, SearchControlsBar, RelevanceThreshold, SearchTotalsHeadline, ApplyLabelButton, getSearchMatchHint, SearchResultsMain, SearchResultsInner, SearchErrorBanner, SearchResultList, SearchGroupCard, SearchNoResults, SearchEmptyState } from '../chunk-G4IYES7G.js';
30
30
  import { SearchHit } from '../chunk-V5HVPQP7.js';
31
31
  import { UsageMeter } from '../chunk-66TA5IBN.js';
32
- import { DataTable } from '../chunk-SLRVI2YU.js';
33
- import '../chunk-AMTWY22T.js';
32
+ import { DataTable, PageHeader } from '../chunk-X6U6L6BG.js';
33
+ import { ThemeEditor } from '../chunk-5ZBXFHZW.js';
34
34
  import { TimelineZoomControl } from '../chunk-4EZVCGRL.js';
35
35
  import '../chunk-UJE32SST.js';
36
36
  import '../chunk-NHZK64TQ.js';
@@ -39,14 +39,14 @@ import '../chunk-NBV56SGU.js';
39
39
  import { ErrorBoundary } from '../chunk-EQ3WRY2N.js';
40
40
  import { LabelMultiSelectView } from '../chunk-JMQLTMJ7.js';
41
41
  import { workspaceKindColor, WorkspaceIdentity } from '../chunk-6MMYWBYS.js';
42
- import { PassagePill, useCopyText } from '../chunk-FUOCCKE4.js';
43
42
  import '../chunk-K4BGOPGG.js';
43
+ import { PassagePill, useCopyText } from '../chunk-FUOCCKE4.js';
44
44
  import '../chunk-ZCOVDK2E.js';
45
45
  import { isDefinitionsLabel, DOCX_MIME_TYPE, toDefinitionSource, definitionLabels } from '../chunk-IYUKJESY.js';
46
46
  import { decodeWhitespaceEntities } from '../chunk-AF6RDAJF.js';
47
- import { EntityChip, StepTraceSummary, StepTrace, getCurrentAgentStepPresentation, AssistantEntity, ThreadActivity, SubAgentLane, getAgentStepPresentation, stepAccent, MODEL_TIER_ICON_MAP, StepRow, StepNarration, StepSummary, StepDetail, StepOutcome, StepParams, GoalCriteria, SubStepGroup, MODEL_TIER_LABELS, fromPlanSteps, latestMessageTime, isSupersededStop, compactThreadActivity, unnotifiedMentions, notifiedLabel, linkedRunsFromActivity, getModelIcon, SubagentRoster, buildLibrarySkills, filterLibrarySkills, SKILL_SOURCE_LABELS, SKILL_TYPE_LABELS, SkillViewToggle, SkillFilterChips, SkillTile, SkillGenerateForm, SkillLibraryDetail, parseSkillFrontmatter, SKILL_MAIN_FILENAME, SkillEditForm, DEFAULT_AGENT_CAPABILITIES, stripPersonaPreamble, AgentCreator, DEFAULT_AGENT_TYPES, DEFAULT_AGENT_TEMPLATES, AgentAvatarField, isValidAgentName, AgentConnectInstructions, TaskRunsDialog, TaskActivityDialog, WorkflowStepBar, ConsentPage, ConsentCard, ConsentHeader, ConsentNotice, ConsentSection, ConsentBulletList, ConsentStrong, ConsentText, ConfigForm, AgentEditView, AgentMainView, AgentCreatedView, AgentCreateView, WorkflowRunStatus, ThreadStatusLine, WorkflowThreadStrip, WorkflowStepAction, WorkflowThreadStartedBy, TaskFlow, useWorkflowUsage, WEB_WORKFLOWS, DASHBOARD_PINNED, CUSTOM_TASK, REMIND_TASK, DASHBOARD_OPERATIONS, sortByRecentUse, taskComposerToCreateRequest, taskComposerToUpdateRequest, composerToWorkflowUpdate, moveTargets, workflowToComposerValues, REMIND_TASK_ID, CUSTOM_TASK_ID, taskToComposerValues, TaskComposer, renderWorkflowIcon, AUTOMATION_EVENTS, TaskPlan, TaskStartDialog, ThreadLauncher, NewThreadDialog, GENERATE_IMAGE_ID, IMAGE_ASPECT_AUTO, deriveAnnotationName, ANNOTATE_ID, recordWorkflowUse, openWorkflowLaunch, useWorkflowLaunchRequest, AgentBar, AgentBarNotes, AgentBarQueuedNote, AgentBarProbeAnswer, BUILTIN_SKILLS, TaskEmptyState, ConsentMessage, CopyableUrl, ConsentPermissionList, ConsentActions, ConsentFootnote, AgentBarStatus, AgentBarIconButton, AgentBarMenu, composePersona, newThreadToRequest, importSkillFile, importSkillFromUrl, WorkflowRunner, skillSlug, serializeSkill, toPlanSteps, useWorkflowView, STATUS_LABELS, asTaskStatus, workflowToSkillMarkdown, closeWorkflowLaunch } from '../chunk-44FPFTU2.js';
47
+ import { EntityChip, StepTraceSummary, StepTrace, getCurrentAgentStepPresentation, AssistantEntity, ThreadActivity, SubAgentLane, getAgentStepPresentation, stepAccent, MODEL_TIER_ICON_MAP, StepRow, StepNarration, StepSummary, StepDetail, StepOutcome, StepParams, GoalCriteria, SubStepGroup, MODEL_TIER_LABELS, fromPlanSteps, latestMessageTime, isSupersededStop, compactThreadActivity, unnotifiedMentions, notifiedLabel, linkedRunsFromActivity, getModelIcon, SubagentRoster, buildLibrarySkills, filterLibrarySkills, SKILL_SOURCE_LABELS, SKILL_TYPE_LABELS, SkillViewToggle, SkillFilterChips, SkillTile, SkillGenerateForm, SkillLibraryDetail, parseSkillFrontmatter, SKILL_MAIN_FILENAME, SkillEditForm, DEFAULT_AGENT_CAPABILITIES, stripPersonaPreamble, AgentCreator, DEFAULT_AGENT_TYPES, DEFAULT_AGENT_TEMPLATES, AgentAvatarField, isValidAgentName, AgentConnectInstructions, TaskRunsDialog, TaskActivityDialog, WorkflowStepBar, ConsentPage, ConsentCard, ConsentHeader, ConsentNotice, ConsentSection, ConsentBulletList, ConsentStrong, ConsentText, ConfigForm, AgentEditView, AgentMainView, AgentCreatedView, AgentCreateView, WorkflowRunStatus, ThreadStatusLine, WorkflowThreadStrip, WorkflowStepAction, WorkflowThreadStartedBy, TaskFlow, useWorkflowUsage, WEB_WORKFLOWS, DASHBOARD_PINNED, CUSTOM_TASK, REMIND_TASK, DASHBOARD_OPERATIONS, sortByRecentUse, taskComposerToCreateRequest, taskComposerToUpdateRequest, composerToWorkflowUpdate, moveTargets, workflowToComposerValues, REMIND_TASK_ID, CUSTOM_TASK_ID, taskToComposerValues, TaskComposer, renderWorkflowIcon, AUTOMATION_EVENTS, TaskPlan, TaskStartDialog, ThreadLauncher, NewThreadDialog, GENERATE_IMAGE_ID, IMAGE_ASPECT_AUTO, deriveAnnotationName, ANNOTATE_ID, recordWorkflowUse, openWorkflowLaunch, useWorkflowLaunchRequest, AgentBar, AgentBarNotes, AgentBarQueuedNote, AgentBarProbeAnswer, BUILTIN_SKILLS, TaskEmptyState, ConsentMessage, CopyableUrl, ConsentPermissionList, ConsentActions, ConsentFootnote, AgentBarStatus, AgentBarIconButton, AgentBarMenu, composePersona, newThreadToRequest, importSkillFile, importSkillFromUrl, WorkflowRunner, skillSlug, serializeSkill, toPlanSteps, useWorkflowView, STATUS_LABELS, asTaskStatus, workflowToSkillMarkdown, closeWorkflowLaunch } from '../chunk-ORUV4MEP.js';
48
48
  import { MultiSelect } from '../chunk-CQCC7LE7.js';
49
- import { PersonPill, documentScopeLabels, matchWorkflowScope } from '../chunk-7S76Q5RK.js';
49
+ import { PersonPill, documentScopeLabels, matchWorkflowScope } from '../chunk-GA2A7OX6.js';
50
50
  import { SectionLabel } from '../chunk-MQEN62NR.js';
51
51
  import { TriStateFilterMenu } from '../chunk-G4GLDQLY.js';
52
52
  import '../chunk-M4S75AEJ.js';
@@ -59,9 +59,6 @@ import { GridView } from '../chunk-7F5Z4K5W.js';
59
59
  import { StreamedArtifactFrame } from '../chunk-LOJVUGBJ.js';
60
60
  import { DEFAULT_PASSWORD_RULES, AccountRecoveryDialog, promptSaveCredential, useFragmentCredentials, AuthLayout, AuthHeading, AuthField, AuthInput, AuthFieldBadge, AuthLink, AuthNote, RevealablePasswordInput, AuthConsent, AuthSubmitButton, AuthDivider, AuthAlert, RecoveryKeyDialog, parseAuthError, AuthOfflineBadge, AuthTabs, splitAuthHash, withTrailingFragment } from '../chunk-VN4FSGBR.js';
61
61
  import { PasswordStrengthInput } from '../chunk-P6OLZGQA.js';
62
- import { attendeeKey, upcomingOf, conferenceUrl, isWebinarConference, canJoinEvent, calendarToListItem, buildGridEvents, pendingCreateToGrid, newEventDraft, MiniMonth, CalendarList, CalendarGrid, printCalendar, EventDetails, ScopeDialog, CalendarFormDialog, ProposeTimeDialog, isCalendarAttachment, parseIcsInvite, formatEventWhen, groupSlotsByDay, publicBookingMessage, formatSlotRange, zoneOptions, buildTimeChangeRequest, eventToDraft, needsScope, validateDraft, CALENDAR_DEFAULT_LABELS, buildCreateBody, buildDeleteTarget, EventEditor, toSettingsValue, CalendarSettingsForm, describeCalendarError, normalizeFeedUrl, parseOverlayLink, isAllDayDraft, draftRangeUtc, freeBusyToRows, SchedulingAssistant, applySuggestion, toSuggestionViews, bookingLink, defaultRoomWindow, bookingToForm, emptyBookingForm, slugify, WeeklyHoursEditor, validateBookingForm, formToBookingBody, WEEKDAY_NAMES, formatBusy, buildEditRequest } from '../chunk-AWVGKHJT.js';
63
- import { detectTimeZone, utcToDate, formatPlainDate, formatInZone, safeZone, todayInZone, addDays, listTimeZones, wallToUtc } from '../chunk-OJIX5NBN.js';
64
- import { DocumentPicker } from '../chunk-WNDIVNPT.js';
65
62
  import { useTranscriptRuns, TranscriptEntry, ThreadCallLogCard, RecordingCard, useMeetingThreadMessages, threadTranscriptRuns, useProvisionalSpeakers, TranscriptRunsContext, ProvisionalSpeakers, CallConversationEmpty } from '../chunk-7JJ7LU3T.js';
66
63
  export { useMeetingThreadMessages } from '../chunk-7JJ7LU3T.js';
67
64
  import { parseCallLogDetail } from '../chunk-S3YRRD54.js';
@@ -91,14 +88,17 @@ export { requestCalendarComposer, requestCalendarEvent, useCalendarViewStore } f
91
88
  import { ConfirmDialog } from '../chunk-U4HWVCRN.js';
92
89
  import { ModalHeader, ModalScaffold, ModalSection, ModalSectionTitle } from '../chunk-TX2ZICS7.js';
93
90
  import '../chunk-7F6CBP3Z.js';
91
+ import { attendeeKey, upcomingOf, conferenceUrl, isWebinarConference, canJoinEvent, calendarToListItem, buildGridEvents, pendingCreateToGrid, newEventDraft, MiniMonth, CalendarList, CalendarGrid, printCalendar, EventDetails, ScopeDialog, CalendarFormDialog, ProposeTimeDialog, isCalendarAttachment, parseIcsInvite, formatEventWhen, groupSlotsByDay, publicBookingMessage, formatSlotRange, zoneOptions, buildTimeChangeRequest, eventToDraft, needsScope, validateDraft, CALENDAR_DEFAULT_LABELS, buildCreateBody, buildDeleteTarget, EventEditor, toSettingsValue, CalendarSettingsForm, describeCalendarError, normalizeFeedUrl, parseOverlayLink, isAllDayDraft, draftRangeUtc, freeBusyToRows, SchedulingAssistant, applySuggestion, toSuggestionViews, bookingLink, defaultRoomWindow, bookingToForm, emptyBookingForm, slugify, WeeklyHoursEditor, validateBookingForm, formToBookingBody, WEEKDAY_NAMES, formatBusy, buildEditRequest } from '../chunk-AWVGKHJT.js';
92
+ import { detectTimeZone, utcToDate, formatPlainDate, formatInZone, safeZone, todayInZone, addDays, listTimeZones, wallToUtc } from '../chunk-OJIX5NBN.js';
93
+ import { DocumentPicker } from '../chunk-WNDIVNPT.js';
94
94
  import '../chunk-VUNV25KB.js';
95
95
  import { QueryClient, useQueryClient, QueryClientProvider } from '@tanstack/react-query';
96
96
  import { useWorkspaces, ArbiBotHeadIcon, IN_FLIGHT_DOCUMENT_STATUSES, useOfflineDocumentIds, useOpenViewerDocumentId, FINISHED_DOCUMENT_STATUSES, useMailPolicy, useProcessingTasks, resolveDocumentStatus, useArbi, useIsCreatingTag, HtmlIcon, useUpdateDocuments, useDeleteDocuments, useRenameFolder, useDownloadDocuments, useTags, useDocumentHostActions, useDocumentThumbnails, useArbiSessionState, selectDraft, useArbiSessionStore, useAudioRecorder, MicRecordingOverlay, useArbiWsStatus, useArbiWsStore, useUserSettings, useProcessingTask, useDocumentPendingSync, useWorkspaceUsers, useMessageTimer, useDocuments, useAvailableModels, formatGbp, CitationRenderer, useArbiSession, buildMentionCandidates, useConversations, ASSISTANT_MENTION_LABEL, useConversationItems, useDeleteMessage, useArbiHost, transcriptSegmentOf, useConfig, useThinkingContent, useCreateFact, useCreateFacts, workflowStepOf, stripSpeakerPrefix, MessageArtifactCard, useConversationData, useBranchNavigation, useSkills, useBuiltinCommands, useDocumentsSupport, useConversationActivity, useMessageDetails, useWorkflows, getWorkspaceKind, resolveConfigModel, useRunConversation, useWorkspaceActivity, callLink, openCall, startDmCall, calendarQueryKeys, mailQueryKeys, arbiQueryKeys, invalidateConversationLists, isWorkspaceNotificationType, useNotifications, useDeleteNotifications, useMarkNotificationsRead, useCallsEnabled, serverNotificationBellEntry, documentDisplayName, useWorkspaceNotificationLevel, useFollowThread, useUploadSkillFiles, useSaveSkill, useSetSkillVisibility, useDeleteSkill, useSkillSource, useAgentModels, useMcpTools, useAgentConfig, useAgentWorkspaces, useCreateAgent, useSaveAgentConfig, useGrantAgentAccess, useRevokeAgentAccess, useGenerateAgentAvatar, useWorkflowRuns, useAgents, ArtifactCanvas, ConversationScope, useConversation, useTagKindSchema, useCreateTag, useSetTagValues, useUpdateTagKindSchema, useUpdateTag, useFacts, useDeleteTag, useExtractEntities, useEntityExtractionDocIds, useStartWorkspaceTransfer, useResumeWorkspaceTransfer, useCancelWorkspaceTransfer, useWorkspaceTransfer, useWorkspaceTransfers, useWorkspaceExportDownload, usePlanWorkspaceTransfer, isTransferResumable, isTransferFinished, useShellWorkspaces, useProfile, useUpdateProfile, useRequestEmailChange, useConfirmEmailChange, useNameEditor, useAvatarCrop, useEmailChange, ImageCropModal, useIdentityVerification, usePasswordChange, usePasswordChangeForm, useNotificationPreferences, useSessions, useCurrentSessionId, useTerminateSession, useSignOut, useDeleteAccount, useDeleteAccountFlow, useMailClient, defaultMailAlias, useClaimNativeAlias, useMailOnline, useConnectMailAccount, useDisconnectMailAccount, useMailAccounts, useUpdateUserSettings, useConnectorVendorVisibility, useConnectorCatalog, useMyConnectors, useDisconnectConnector, useSlackConnection, useDisconnectSlack, isMailboxSyncVendor, isSharePointVendor, useWorkspaceTrash, useInvalidateStorage, useStorageActions, useStorageItems, useStorageItemNames, useStorageProjects, useUserUsageToday, useStorageSnapshots, useUpdateWorkspace, useAddWorkspaceMembers, useRemoveWorkspaceMembers, useSetWorkspaceMemberRoles, toShellWorkspace, useEnableMailboxSync, useMailboxFolders, useEnableDriveSync, useDriveFolderChildren, connectorErrorStatus, useProjectInvoices, useProjects, useUpdateProjectFields, useChargeWatch, useAddonQuote, STILL_WORKING, useProjectBillingPortal, useProjectUsage, useIsSlow, useProducts, useCreateProject, useDeleteProject, useRefreshProject, useBoxRole, useContacts, useInviteContacts, useCanCreateProjects, useDeleteWorkspaces, PROJECT_CREATION_DENIED_REASON, useCreateContact, useUpdateContact, useLinkContact, useEntitlements, useImportContacts, entitlementRefusal, useDeleteContact, MAX_RETRIEVE_DOC_IDS, useSemanticSearch, useAssignDocTags, useMailUnlock, useMailFolders, useMailMessages, useMailDraftCompose, useMailMessage, useMailCache, MailOfflineUnavailableError, accountPath, useCalendarEvents, useCalendars, useCanHostCalls, useOpenCallMeetingChat, usePeople, useFetchCalendarEvent, useCalendarSettings, useCalendarOverlays, useCalendarOutbox, useCalendarAccounts, useSyncAccountsOnOpen, useResumeCalendarAccountConnect, useCreateEvent, useUpdateEvent, useDeleteEvent, useMoveEvent, useRespondToEvent, useCreateCalendar, useUpdateCalendar, useDeleteCalendar, useImportCalendar, useSaveCalendarSettings, useRefreshCalendar, useCalendarEvent, useMailAttachmentText, useCalendarEventByUid, getPublicBookingPage, bookPublicSlot, PublicBookingError, isZipFile, prepareUploadFiles, UPLOAD_MAX_FILE_SIZE, filesFromDrop, UPLOAD_ACCEPT, useUploadFromUrls, useUploadFiles, useUpdateDocTag, useRemoveDocTags, subscribeDocumentRows, useGenerateDocTags, useDocumentsLoading, selectViewingDocumentId, useRelatedDocuments, myChatId, useChatThread, useChatPost, useDeleteChatMessage, useMarkChatRead, setOpenChat, useAgentDmStatus, annotateThread, userDisplayName, DmComposer, TypingIndicator, useRenameChat, useAddChatMembers, useRemoveChatMember, useChats, useChatSummaries, useCreateGroupChat, useApplyChatModel, AUTO_CHAT_MODEL, formatGbpPerMillionTokens, useConfigSchema, useSaveConfig, useConversationPendingAuth, openAccessRequest, useRequestWorkspaceAccess, threadTabId, useUpdateConversation, useCanEditShared, useActOnStep, useCreateWork, useRunWorkflow, useStartTaskQuery, useCreateWorkflow, useUpdateWorkflow, usePlanWork, useWorkItems, TaskThreadPendingError, useMentionCandidates, useAgentRunControl, useConnectRunStream, useAnswerAgentQuestion, useConversationIsShared, useWorkspaceRole, buildPendingFirstTurn, useConversationTurn, useAskAgain, getOrphanedLastMessage, refuseChatWhenOffline, useThreadDocument, useDocumentAutoAdd, useAutoSendDraft, READ_ONLY_MEETING_TEXT, useAgentSession, useStartAgentSession, useCloseAgentSession, downloadRecoveryFile, LinkedInIcon, GoogleIcon, AppleIcon, useCurrentUser, isQueuedCalendarWrite, DateSeparator, ChatBubble, isAliasTakenError, nextAliasSuggestion, aliasTakenMessage, mailJson, connectorReturnTo, DmAvatar, ConversationList, GitHubIcon, getRelatedTotal, isDeploymentUserNotification, describeServerNotification, getWorkspaceActionText, getWorkspaceSentPhrase, BOX_SEAT_REFUSED, BOX_SEAT_REFUSED_TITLE, documentActivityPhrase, isSignatureNotificationType, inputRequestTitle, WORK_NOTIFICATION_LABELS, useConversationThreads, usePassageQuotes, useUpdateFact, useDeleteFact, useAccountClient, useDriveFolderDocCount, useChangeProjectPlan, useCancelProjectSubscription, usePreviewProjectPlanChange, useAddProjectAddonBlock, usePlanQuote, useCreateProjectCheckout, useInvalidateProjects, fileAttachment, useMailProjects, useSaveMailDraft, useSendMail, useMailDraftReplaced, useCalendarInvitations, useDecideCounter, useSearchContacts, usePublishCalendar, useCalendarShares, useShareCalendar, useUnshareCalendar, useSubscribeCalendar, useHolidayCountries, useAddHolidayCalendar, cancelPublicBooking, useInvalidateAfterTransfer, useConfigs, useSaveConfigField, useDeleteConfig, isFullConfig, AiAnswer, ArbiWebSocketProvider, signatureNotificationPhrase, signatureRequestMeta, getNotificationTypeMeta, useMailDraftEditor, useFreeBusy, useFindTime, useCalendarSupport, useStartCalendarAccountOAuth, useConnectOAuthAccount, useBookingPages, useDeleteBookingPage, useRooms, SHAREPOINT_VENDORS, useUpdateProjectNextPeriodAddons, useUpdateProjectAddonSettings, useSyncCalendarAccount, useUpdateCalendarAccount, useDisconnectCalendarAccount, ACCOUNT_VENDOR, useCalDavProfiles, useConnectCalDavAccount, useSaveBookingPage, useCreateRoom } from '@arbidocs/react';
97
97
  import { mergeAgentSteps, extractSubagentLanes, getCurrentStep, computeRunStats, formatTokens, isNearAiUsageBudget, getSubagentBranchRecord, buildCitationChunkData, topLevelAgentSteps, findMainSiblingLeaf, sliceToSubagentThread, getAgentStepLabel, subagentJobLabel, getStepDisplay, getStepTool, findLeafForTaskMessage, Arbi, FLAT_TAG_KINDS, getEligibleParentTags, canTagHaveParent, isFlatKind, TAG_NESTING_MAX_DEPTH, TAG_KINDS, formatFileSize, filterDocumentTags, isLabelTag, refusalReason, isPresenceTag, isAnnotationTag, flattenTagTree, tagsForScope, tagsOfGroup, chats, buildRetrievalFullContextTool, buildRetrievalChunkTool, getChildTags, tagUseCount, ArbiApiError, PRESENCE_KINDS, isEntityTag, DuplicateContactError, wouldCreateTagCycle, getTagDescendantIds } from '@arbidocs/sdk/browser';
98
98
  import { browserSessionStateStorage, parseCallFragment, validateRecoveryKeyFile, RECOVERY_KEY_ERRORS, parseRecoveryUrl, prewarmKeyPairs, decryptRecoveryKey, unlockIdentityWithPassword, createRecoveryUrl, bytesToBase64, initSodium } from '@arbidocs/client';
99
99
  import React7, { memo, useMemo, lazy, useRef, useEffect, useCallback, useState, forwardRef, useLayoutEffect, useImperativeHandle, createContext, useContext, useSyncExternalStore, Suspense, Fragment as Fragment$1, useId } from 'react';
100
- import { Users, MessageCircleMore, SquarePen, BookOpen, MessagesSquare, Pencil, Download, Mail, FolderInput, Trash2, Eye, Sparkles, Play, ArrowDownToLine, RefreshCw, Zap, AlertTriangle, FileX, SkipForward, Loader2, Clock, CheckCircle, ArrowUpRight, Send, Settings, Edit3, Copy, Link, Share2, Check, Milestone, RotateCcw, FileText, Network, ChevronRight, Bell, Activity, Info, UserCheck, Upload, Link2, Search, Plus, ArrowLeft, ExternalLink as ExternalLink$1, Tags, CheckCircle2, Monitor, UserCircle, KeyRound, Radio, LogOut, Wifi, Lock, HardDrive, User, HatGlasses, MessageSquare, PlugZap, Gauge, Cloud, XCircle, Building2, Printer, SquareStack, Table, Cake, X, UserRound, Star, Tag, Video, CalendarDays, MapPin, Globe, Calendar, Hash, File as File$1, FileType, FolderOpen, Fingerprint, Paperclip, CircleCheck, TriangleAlert, LoaderCircle, NotebookPen, Columns3, EyeOff, ArrowUp, ArrowDown, ZoomOut, Camera, FilePlus2, UserMinus, UserPlus, UsersRound, Code2, Infinity, ChevronDown, MoreHorizontal, Wrench, RotateCw, Square, BadgeCheck, Shield, ClipboardList, ArrowUpCircle, Contact, Scale, BookA, Quote, Inbox, CalendarX, CalendarCheck, Phone, Pause, Minimize2, Maximize2, Minus, CalendarSearch, DoorOpen, AlertCircle } from 'lucide-react';
101
- import { isAgent, UserEntity, getUserInitials, getUserDisplayName, getUserAvatarColor, agentAvatarColors, Avatar, AvatarImage, AvatarFallback, cn, ShieldIcon, getWorkspaceColor, getFileTypeIcon, DocumentEntity, getDocumentTitle, formatFolderLabel, getEntityLabel, getEntityColor, VisibilityIcon, formatFriendlyDate, getDocumentSubject, Badge, getTagTypeIcon, getTagTypeLabel, VisibilityToggle, TagEntity, ThreadVisibilityIcon, Button, isImageDocument, Tooltip, TooltipTrigger, TooltipContent, Dialog, DialogContent, formatRelativeTime, ProviderIcon, EntityIcon, Label, Input, Textarea, DialogHeader, DialogTitle, DialogDescription, tagKindNouns, tagKindTitle, IconToggle, Switch, Checkbox, DialogTrigger, ProjectEntity, DialogFooter, getDocIcon, getDocumentNature, getDocumentAuthor, markdownToPlainText, formatDocDate, getDocumentDate, friendlyFileType, canonicalFolderPath, DebouncedInput, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Slider, AgentBadge, PresenceLabel, TooltipProvider, EntityPill, Popover, PopoverAnchor, PopoverTrigger, PopoverContent, Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, ScrollArea, ArbiIcon, Tabs, TabsList, TabsTrigger, TabsContent, ARBI_MARK_SRC, VerifiedToggle, Progress } from '@arbidocs/react/ui';
100
+ import { Users, MessageCircleMore, SquarePen, BookOpen, MessagesSquare, Pencil, Download, Mail, FolderInput, Trash2, Eye, Sparkles, Play, ArrowDownToLine, RefreshCw, Zap, AlertTriangle, FileX, SkipForward, Loader2, Clock, CheckCircle, ArrowUpRight, Send, Settings, Edit3, Copy, Link, Share2, Check, Milestone, RotateCcw, FileText, Network, ChevronRight, Bell, Activity, Info, UserCheck, Upload, Link2, Search, Plus, ArrowLeft, ExternalLink as ExternalLink$1, Tags, CheckCircle2, Monitor, UserCircle, KeyRound, Radio, LogOut, Wifi, Lock, HardDrive, User, HatGlasses, MessageSquare, PlugZap, Gauge, Cloud, XCircle, Building2, Palette, Type, Printer, SquareStack, Table, Cake, X, UserRound, Star, Tag, Video, CalendarDays, MapPin, Globe, Calendar, Hash, File as File$1, FileType, FolderOpen, Fingerprint, Paperclip, CircleCheck, TriangleAlert, LoaderCircle, NotebookPen, Columns3, EyeOff, ArrowUp, ArrowDown, ZoomOut, Camera, FilePlus2, UserMinus, UserPlus, UsersRound, Code2, Infinity, ChevronDown, MoreHorizontal, Wrench, RotateCw, Square, BadgeCheck, Shield, ClipboardList, ArrowUpCircle, Contact, Scale, BookA, Quote, Inbox, CalendarX, CalendarCheck, Phone, LogIn, Pause, Minimize2, Maximize2, Minus, CalendarSearch, DoorOpen, AlertCircle } from 'lucide-react';
101
+ import { isAgent, UserEntity, getUserInitials, getUserDisplayName, getUserAvatarColor, agentAvatarColors, Avatar, AvatarImage, AvatarFallback, cn, ShieldIcon, getWorkspaceColor, getFileTypeIcon, DocumentEntity, getDocumentTitle, formatFolderLabel, getEntityLabel, getEntityColor, VisibilityIcon, formatFriendlyDate, getDocumentSubject, Badge, getTagTypeIcon, getTagTypeLabel, VisibilityToggle, TagEntity, ThreadVisibilityIcon, Button, isImageDocument, Tooltip, TooltipTrigger, TooltipContent, Dialog, DialogContent, formatRelativeTime, ProviderIcon, EntityIcon, Label, Input, Textarea, DialogHeader, DialogTitle, DialogDescription, tagKindNouns, tagKindTitle, IconToggle, Switch, Checkbox, entityNoun, DialogTrigger, ProjectEntity, DialogFooter, getDocIcon, getDocumentNature, getDocumentAuthor, markdownToPlainText, formatDocDate, getDocumentDate, friendlyFileType, canonicalFolderPath, DebouncedInput, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Slider, AgentBadge, PresenceLabel, TooltipProvider, EntityPill, Popover, PopoverAnchor, PopoverTrigger, PopoverContent, Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, ScrollArea, ArbiIcon, Tabs, TabsList, TabsTrigger, TabsContent, ARBI_MARK_SRC, VerifiedToggle, Progress } from '@arbidocs/react/ui';
102
102
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
103
103
  import { hasMessageBody, notify, linkMentions, useNotify, sharedSearchSession, takePendingSearch, useTurnDocumentId, useOpenDocumentId, useRegisterOpenDocument } from '@arbidocs/react/shell';
104
104
  import { SIGNED_LOCKED_REASON, isSignedVersion, currentHasMarkup, fetchMarkupPdf, downloadBlob, useIsOnline, DocumentToolsProvider, useOptionalDocumentTools, fetchDocumentPdf, useSignatureVerification, SignatureVerificationError } from '@arbidocs/react/document-tools';
@@ -9941,6 +9941,62 @@ function organisationSettingsSection({
9941
9941
  )
9942
9942
  };
9943
9943
  }
9944
+ function appearanceSettingsSection(options2) {
9945
+ const TabIcon = options2.theme ? Palette : Type;
9946
+ return {
9947
+ id: "appearance",
9948
+ label: "Appearance",
9949
+ icon: /* @__PURE__ */ jsx(TabIcon, { className: "w-6 h-6" }),
9950
+ render: () => /* @__PURE__ */ jsx(AppearanceSection, { ...options2 })
9951
+ };
9952
+ }
9953
+ function AppearanceSection({
9954
+ appearance,
9955
+ theme,
9956
+ themePreview,
9957
+ icon: icon2 = /* @__PURE__ */ jsx(Palette, { className: "size-4" }),
9958
+ description = "Colours and type on this device."
9959
+ }) {
9960
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
9961
+ appearance && /* @__PURE__ */ jsx(ReaderAppearance, { bundle: appearance }),
9962
+ theme && /* @__PURE__ */ jsx(
9963
+ SettingsSection,
9964
+ {
9965
+ icon: icon2,
9966
+ title: "Appearance",
9967
+ description,
9968
+ testId: appearance ? "settings-appearance-theme" : "settings-appearance",
9969
+ children: /* @__PURE__ */ jsx(
9970
+ ThemeEditor,
9971
+ {
9972
+ bundle: theme,
9973
+ variant: "collapsed",
9974
+ preview: themePreview,
9975
+ testIdPrefix: "settings-theme"
9976
+ }
9977
+ )
9978
+ }
9979
+ )
9980
+ ] });
9981
+ }
9982
+ function ReaderAppearance({ bundle }) {
9983
+ const state = bundle.useStore();
9984
+ const { defaults } = bundle;
9985
+ const isDefault = state.pairingId === defaults.pairingId && state.colorScheme === defaults.colorScheme && state.textSize === defaults.textSize;
9986
+ return /* @__PURE__ */ jsx(
9987
+ AppearanceSettings,
9988
+ {
9989
+ colorScheme: state.colorScheme,
9990
+ onColorSchemeChange: state.setColorScheme,
9991
+ textSize: state.textSize,
9992
+ onTextSizeChange: state.setTextSize,
9993
+ pairingId: state.pairingId,
9994
+ onPairingChange: state.setPairing,
9995
+ pairingIds: bundle.pairingIds,
9996
+ onReset: isDefault ? void 0 : state.reset
9997
+ }
9998
+ );
9999
+ }
9944
10000
  function ConnectedProjectStorage({ projectExtId }) {
9945
10001
  const { data, isLoading } = useStorageProjects("mine", projectExtId);
9946
10002
  const project = data?.projects.find((p) => p.project_ext_id === projectExtId);
@@ -9969,7 +10025,7 @@ function ConnectedDeploymentStorage() {
9969
10025
  const projectColumns = [
9970
10026
  {
9971
10027
  key: "name",
9972
- header: view === "people" ? "Person" : "Project",
10028
+ header: view === "people" ? "Person" : getEntityLabel("PROJECT"),
9973
10029
  render: (p) => /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
9974
10030
  /* @__PURE__ */ jsx("div", { className: "truncate font-medium text-foreground", children: view === "people" ? p.owner_email ?? p.name : p.name }),
9975
10031
  view !== "people" && p.owner_email && /* @__PURE__ */ jsx("div", { className: "truncate text-xs text-muted-foreground", children: p.owner_email })
@@ -10056,7 +10112,7 @@ function ConnectedDeploymentStorage() {
10056
10112
  (deployment.orphaned_bytes > 0 || deployment.unattributed_bytes > 0) && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", "data-testid": "deployment-storage-unowned", children: [
10057
10113
  formatBytes(deployment.orphaned_bytes),
10058
10114
  " left behind by deleted items (removed by the next monthly clean-up)",
10059
- deployment.unattributed_bytes > 0 && ` \xB7 ${formatBytes(deployment.unattributed_bytes)} not owned by any project`
10115
+ deployment.unattributed_bytes > 0 && ` \xB7 ${formatBytes(deployment.unattributed_bytes)} not owned by any ${entityNoun("PROJECT")}`
10060
10116
  ] }),
10061
10117
  trend.dates.length > 1 && /* @__PURE__ */ jsx(
10062
10118
  UsageLineChart,
@@ -10074,7 +10130,7 @@ function ConnectedDeploymentStorage() {
10074
10130
  onChange: setView,
10075
10131
  ariaLabel: "Storage by",
10076
10132
  options: [
10077
- { value: "projects", label: "Projects" },
10133
+ { value: "projects", label: getEntityLabel("PROJECT", "PLURAL") },
10078
10134
  { value: "people", label: "People" },
10079
10135
  { value: "items", label: "Largest items" }
10080
10136
  ]
@@ -10096,7 +10152,7 @@ function ConnectedDeploymentStorage() {
10096
10152
  rows: [...view === "people" ? people : projects].sort(byBytes),
10097
10153
  getRowId: (p) => p.project_ext_id,
10098
10154
  area: "deployment-storage-projects",
10099
- emptyTitle: view === "people" ? "No personal storage yet" : "No projects yet"
10155
+ emptyTitle: view === "people" ? "No personal storage yet" : `No ${entityNoun("PROJECT", "PLURAL")} yet`
10100
10156
  }
10101
10157
  )
10102
10158
  ]
@@ -12043,11 +12099,11 @@ var sentence = (text2) => text2.trim().replace(/[.;:,\s]+$/, "");
12043
12099
  function refusal(what, next) {
12044
12100
  return `${sentence(what)}. Nothing was charged. ${sentence(next)}.`;
12045
12101
  }
12046
-
12047
- // src/connection/billing/useAddonPurchase.ts
12048
12102
  var FALLBACK_MESSAGES = {
12049
12103
  PAYMENT_DECLINED: "Card declined. Update your card and try again.",
12050
- PAYMENT_METHOD_REQUIRED: "Add a card to this project first.",
12104
+ get PAYMENT_METHOD_REQUIRED() {
12105
+ return `Add a card to this ${entityNoun("PROJECT")} first.`;
12106
+ },
12051
12107
  BILLING_ADDRESS_REQUIRED: "Add a billing address first."
12052
12108
  };
12053
12109
  function addonErrorMessage(error) {
@@ -12062,11 +12118,15 @@ function addonErrorMessage(error) {
12062
12118
  }
12063
12119
  var REFUSALS = {
12064
12120
  PAYMENT_DECLINED: refusal("Card declined", "Update your card and try again"),
12065
- PAYMENT_METHOD_REQUIRED: refusal("No card on this project", "Add one with Update card"),
12066
- BILLING_ADDRESS_REQUIRED: refusal(
12067
- "No billing address on this project",
12068
- "Add one with Update card"
12069
- )
12121
+ get PAYMENT_METHOD_REQUIRED() {
12122
+ return refusal(`No card on this ${entityNoun("PROJECT")}`, "Add one with Update card");
12123
+ },
12124
+ get BILLING_ADDRESS_REQUIRED() {
12125
+ return refusal(
12126
+ `No billing address on this ${entityNoun("PROJECT")}`,
12127
+ "Add one with Update card"
12128
+ );
12129
+ }
12070
12130
  };
12071
12131
  function chargeRefusalMessage(error) {
12072
12132
  const code = addonErrorCode(error);
@@ -12387,9 +12447,9 @@ function ProjectsTable() {
12387
12447
  {
12388
12448
  onSuccess: () => {
12389
12449
  setRenameTarget(null);
12390
- notify.success("Project renamed");
12450
+ notify.success(`${getEntityLabel("PROJECT")} renamed`);
12391
12451
  },
12392
- onError: () => notify.error("Failed to rename project")
12452
+ onError: () => notify.error(`Failed to rename ${entityNoun("PROJECT")}`)
12393
12453
  }
12394
12454
  );
12395
12455
  }, [renameTarget, renameValue, updateProject]);
@@ -12478,26 +12538,32 @@ function SharedProjects() {
12478
12538
  );
12479
12539
  if (shared.length === 0) return null;
12480
12540
  const usedToday = usageToday?.used_gbp ?? 0;
12481
- return /* @__PURE__ */ jsx(SharedProjectsSection, { footnote: "Your daily AI usage allowance in projects other people run \u2014 their plan and billing are theirs.", children: shared.map((p) => {
12482
- const cap = p.daily_cap_per_user;
12483
- return /* @__PURE__ */ jsx(
12484
- SharedProjectRow,
12485
- {
12486
- testId: `shared-project-${p.external_id}`,
12487
- identity: /* @__PURE__ */ jsx(BillingProjectEntity, { name: p.name, relation: "other", size: "sm" }),
12488
- allowance: cap != null && cap > 0 ? /* @__PURE__ */ jsx(
12489
- UsageMeter,
12541
+ return /* @__PURE__ */ jsx(
12542
+ SharedProjectsSection,
12543
+ {
12544
+ footnote: `Your daily AI usage allowance in ${entityNoun("PROJECT", "PLURAL")} other people run \u2014 their plan and billing are theirs.`,
12545
+ children: shared.map((p) => {
12546
+ const cap = p.daily_cap_per_user;
12547
+ return /* @__PURE__ */ jsx(
12548
+ SharedProjectRow,
12490
12549
  {
12491
- label: "Today",
12492
- value: `${formatGbp(usedToday)} / ${formatGbp(cap)}`,
12493
- pct: usedToday / cap * 100,
12494
- testId: `shared-project-allowance-${p.external_id}`
12495
- }
12496
- ) : /* @__PURE__ */ jsx("p", { className: "text-right text-xs text-muted-foreground", children: "No daily limit" })
12497
- },
12498
- p.external_id
12499
- );
12500
- }) });
12550
+ testId: `shared-project-${p.external_id}`,
12551
+ identity: /* @__PURE__ */ jsx(BillingProjectEntity, { name: p.name, relation: "other", size: "sm" }),
12552
+ allowance: cap != null && cap > 0 ? /* @__PURE__ */ jsx(
12553
+ UsageMeter,
12554
+ {
12555
+ label: "Today",
12556
+ value: `${formatGbp(usedToday)} / ${formatGbp(cap)}`,
12557
+ pct: usedToday / cap * 100,
12558
+ testId: `shared-project-allowance-${p.external_id}`
12559
+ }
12560
+ ) : /* @__PURE__ */ jsx("p", { className: "text-right text-xs text-muted-foreground", children: "No daily limit" })
12561
+ },
12562
+ p.external_id
12563
+ );
12564
+ })
12565
+ }
12566
+ );
12501
12567
  }
12502
12568
  var capText = (cap) => cap != null ? String(cap) : "";
12503
12569
  function DailyCapEditor({ project }) {
@@ -13776,15 +13842,19 @@ function ProjectDetail({ projectExtId, storage }) {
13776
13842
  {
13777
13843
  onSuccess: () => {
13778
13844
  setRenameOpen(false);
13779
- notify.success("Project renamed");
13845
+ notify.success(`${getEntityLabel("PROJECT")} renamed`);
13780
13846
  },
13781
- onError: () => notify.error("Failed to rename project")
13847
+ onError: () => notify.error(`Failed to rename ${entityNoun("PROJECT")}`)
13782
13848
  }
13783
13849
  );
13784
13850
  }, [project, renameValue, updateProject]);
13785
13851
  const hasBilling = stripeEnabled && project?.subscription !== "dev";
13786
13852
  if (isLoading) {
13787
- return /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground p-6", children: "Loading project..." });
13853
+ return /* @__PURE__ */ jsxs("div", { className: "text-sm text-muted-foreground p-6", children: [
13854
+ "Loading ",
13855
+ entityNoun("PROJECT"),
13856
+ "..."
13857
+ ] });
13788
13858
  }
13789
13859
  if (!project) {
13790
13860
  return /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground p-6", "data-testid": "project-detail-missing", children: "This project is no longer available." });
@@ -13846,7 +13916,7 @@ function ProjectDetail({ projectExtId, storage }) {
13846
13916
  /* @__PURE__ */ jsx(ChangePlanDialog, { project, open: planOpen, onOpenChange: setPlanOpen })
13847
13917
  ] });
13848
13918
  }
13849
- function createProjectErrorMessage(error, fallback = "Failed to create project") {
13919
+ function createProjectErrorMessage(error, fallback = `Failed to create ${entityNoun("PROJECT")}`) {
13850
13920
  const detail = apiErrorDetail(error);
13851
13921
  if (typeof detail === "string" && detail) return detail;
13852
13922
  const message = detail?.message;
@@ -13932,7 +14002,7 @@ function NewProjectFlow({ open, onOpenChange, defaultName }) {
13932
14002
  },
13933
14003
  {
13934
14004
  onSuccess: () => {
13935
- notify.success("Project created");
14005
+ notify.success(`${getEntityLabel("PROJECT")} created`);
13936
14006
  setIsCreating(false);
13937
14007
  onOpenChange(false);
13938
14008
  },
@@ -13989,8 +14059,8 @@ function NewProjectFlow({ open, onOpenChange, defaultName }) {
13989
14059
  {
13990
14060
  open,
13991
14061
  onOpenChange: handleOpenChange,
13992
- title: "New project",
13993
- description: stripeEnabled ? "Name it and pick a plan." : "Projects group your workspaces.",
14062
+ title: `New ${entityNoun("PROJECT")}`,
14063
+ description: stripeEnabled ? "Name it and pick a plan." : `${getEntityLabel("PROJECT", "PLURAL")} group your ${entityNoun("WORKSPACE", "PLURAL")}.`,
13994
14064
  showDescription: true,
13995
14065
  size: "xl",
13996
14066
  children: /* @__PURE__ */ jsxs(PlanStack, { gap: 5, children: [
@@ -14002,7 +14072,7 @@ function NewProjectFlow({ open, onOpenChange, defaultName }) {
14002
14072
  id: "new-project-name",
14003
14073
  value: projectName,
14004
14074
  onChange: (e) => setProjectName(e.target.value),
14005
- placeholder: "My Project",
14075
+ placeholder: `My ${getEntityLabel("PROJECT")}`,
14006
14076
  autoFocus: true,
14007
14077
  onKeyDown: (e) => {
14008
14078
  if (e.key === "Enter") submit();
@@ -14078,7 +14148,7 @@ function NewProjectFlow({ open, onOpenChange, defaultName }) {
14078
14148
  )
14079
14149
  ] }) : /* @__PURE__ */ jsx(PlanNotice, { children: "Pro isn't available right now." }))
14080
14150
  ] })),
14081
- /* @__PURE__ */ jsx(PlanActionButton, { onClick: submit, disabled: !canSubmit, children: isCreating ? "Creating\u2026" : isPro ? "Continue to payment" : "Create project" }),
14151
+ /* @__PURE__ */ jsx(PlanActionButton, { onClick: submit, disabled: !canSubmit, children: isCreating ? "Creating\u2026" : isPro ? "Continue to payment" : `Create ${entityNoun("PROJECT")}` }),
14082
14152
  isSlow && /* @__PURE__ */ jsx(PlanNotice, { className: "text-xs", testId: "new-project-still-working", children: "Still working. We'll update here." })
14083
14153
  ] })
14084
14154
  }
@@ -14120,7 +14190,7 @@ function useAutoRefreshPendingProjects() {
14120
14190
  }
14121
14191
  }, [projects, refreshProject, currentUserExtId]);
14122
14192
  }
14123
- var QUOTA_EXCEEDED_MESSAGE = "This project's AI usage for this month is used up.";
14193
+ var quotaExceededMessage = () => `This ${entityNoun("PROJECT")}'s AI usage for this month is used up.`;
14124
14194
  var BOX_MEMBER_QUOTA_MESSAGE = "AI usage for this month is used up. Ask your Box admin to add more.";
14125
14195
  var BOX_ADMIN_QUOTA_MESSAGE = "AI usage for this month is used up. Add more in the ARBI portal.";
14126
14196
  function ConnectedQuotaDialog({ info, onClose: close }) {
@@ -14162,7 +14232,7 @@ function ConnectedQuotaDialog({ info, onClose: close }) {
14162
14232
  close();
14163
14233
  };
14164
14234
  const percent = info && info.budget > 0 ? Math.min(100, Math.round(info.spend / info.budget * 100)) : 100;
14165
- let message = info?.message ?? QUOTA_EXCEEDED_MESSAGE;
14235
+ let message = info?.message ?? quotaExceededMessage();
14166
14236
  let actions = void 0;
14167
14237
  if (box) {
14168
14238
  message = box.isAdmin ? BOX_ADMIN_QUOTA_MESSAGE : BOX_MEMBER_QUOTA_MESSAGE;
@@ -14322,7 +14392,7 @@ function ConnectedWelcomeDialog({
14322
14392
  }
14323
14393
  ) });
14324
14394
  }
14325
- const firstName = currentUser?.given_name;
14395
+ const firstName2 = currentUser?.given_name;
14326
14396
  const hasBalance = balance !== null;
14327
14397
  const quotaItems = getQuotaItems(selectedProject.quotas);
14328
14398
  const resetTs = aiUsageResetTimestamp(selectedProject);
@@ -14332,7 +14402,7 @@ function ConnectedWelcomeDialog({
14332
14402
  {
14333
14403
  open,
14334
14404
  onClose: () => handleOpenChange(false),
14335
- firstName,
14405
+ firstName: firstName2,
14336
14406
  hasReward: hasBalance,
14337
14407
  projectPicker: /* @__PURE__ */ jsx(
14338
14408
  ProjectPicker,
@@ -14636,7 +14706,7 @@ function useConnectedWorkspaceList({
14636
14706
  };
14637
14707
  }
14638
14708
  var WorkspaceTableView = lazy(
14639
- () => import('../WorkspaceTableView-ECPHGWHF.js').then((m) => ({ default: m.WorkspaceTableView }))
14709
+ () => import('../WorkspaceTableView-2XI6FIOO.js').then((m) => ({ default: m.WorkspaceTableView }))
14640
14710
  );
14641
14711
  var WORKSPACES_TAB_ID = "workspaces";
14642
14712
  var defaultRenderMember2 = (user, size) => {
@@ -14775,6 +14845,256 @@ function ConnectedWorkspaceList({
14775
14845
  ) }) }) })
14776
14846
  ] });
14777
14847
  }
14848
+ function workspaceSummary(w) {
14849
+ return {
14850
+ id: w.external_id,
14851
+ name: w.name,
14852
+ description: w.description ?? void 0,
14853
+ isPublic: !!w.is_public,
14854
+ documentCount: workspaceDocumentCount(w),
14855
+ conversationCount: workspaceConversationCount(w),
14856
+ memberCount: w.users?.length ?? 0,
14857
+ filesMb: w.user_files_mb ?? 0,
14858
+ updatedAt: w.updated_at
14859
+ };
14860
+ }
14861
+ function distinctMembers(workspaces) {
14862
+ const byId = /* @__PURE__ */ new Map();
14863
+ for (const w of workspaces) {
14864
+ for (const member of w.users ?? []) {
14865
+ const user = member.user;
14866
+ const id = user?.external_id;
14867
+ if (!id || byId.has(id)) continue;
14868
+ const name = [user.given_name, user.family_name].filter(Boolean).join(" ").trim();
14869
+ byId.set(id, {
14870
+ id,
14871
+ name: name || user.email || "Unknown",
14872
+ email: user.email ?? "",
14873
+ role: member.role ?? "member",
14874
+ isAgent: Boolean(member.agent_ext_id) || isAgentAccount(user)
14875
+ });
14876
+ }
14877
+ }
14878
+ return [...byId.values()];
14879
+ }
14880
+ function buildProjectSummaries(projects, workspaces) {
14881
+ const byProject = /* @__PURE__ */ new Map();
14882
+ for (const w of workspaces ?? []) {
14883
+ const id = w.project_ext_id;
14884
+ if (!id) continue;
14885
+ byProject.set(id, [...byProject.get(id) ?? [], w]);
14886
+ }
14887
+ const summaries = (projects ?? []).map((p) => {
14888
+ const own = byProject.get(p.external_id) ?? [];
14889
+ const storage = p.quotas?.storage_gb;
14890
+ const aiUsage = p.quotas?.ai_usage;
14891
+ const stats = workspaceGroupStats(own);
14892
+ return {
14893
+ id: p.external_id,
14894
+ name: p.name,
14895
+ createdAt: p.created_at,
14896
+ subscription: p.subscription ?? "none",
14897
+ workspaces: own.map(workspaceSummary),
14898
+ workspaceCount: own.length,
14899
+ documentCount: stats.documents,
14900
+ conversationCount: stats.conversations,
14901
+ members: distinctMembers(own),
14902
+ memberCount: stats.members,
14903
+ filesMb: own.reduce((sum, w) => sum + (w.user_files_mb ?? 0), 0),
14904
+ storageUsedGb: storage?.used ?? 0,
14905
+ storageLimitGb: storage?.limit ?? 0,
14906
+ aiUsageUsed: aiUsage?.used ?? 0,
14907
+ aiUsageLimit: aiUsage?.limit ?? 0,
14908
+ client: p.client ?? null,
14909
+ clientRef: p.client_ref ?? null,
14910
+ stage: p.stage ?? null,
14911
+ leadUser: p.lead_user ?? null,
14912
+ budget: p.budget ?? null,
14913
+ fields: p.fields ?? {}
14914
+ };
14915
+ });
14916
+ const work = (s) => s.documentCount + s.conversationCount;
14917
+ return summaries.sort((a, b) => work(b) - work(a));
14918
+ }
14919
+ function useProjectSummaries() {
14920
+ const projects = useProjects();
14921
+ const workspaces = useWorkspaces();
14922
+ const summaries = useMemo(
14923
+ () => buildProjectSummaries(
14924
+ projects.data,
14925
+ workspaces.data
14926
+ ),
14927
+ [projects.data, workspaces.data]
14928
+ );
14929
+ return {
14930
+ projects: summaries,
14931
+ isLoading: projects.isLoading || workspaces.isLoading,
14932
+ isError: projects.isError || workspaces.isError,
14933
+ error: projects.error ?? workspaces.error
14934
+ };
14935
+ }
14936
+ function useProjectSummary(projectId) {
14937
+ const { projects, isLoading, isError } = useProjectSummaries();
14938
+ const project = useMemo(() => projects.find((p) => p.id === projectId), [projects, projectId]);
14939
+ const usage = useProjectUsage(projectId, 0, { enabled: !!projectId });
14940
+ return { project, usage: usage.data, usageLoading: usage.isLoading, isLoading, isError };
14941
+ }
14942
+ function primaryProjectWorkspace(project) {
14943
+ const work = (w) => w.documentCount + w.conversationCount;
14944
+ return [...project.workspaces].sort((a, b) => work(b) - work(a))[0];
14945
+ }
14946
+ var DEFAULT_PROJECT_LIST_COLUMNS = [
14947
+ "name",
14948
+ "client",
14949
+ "stage",
14950
+ "documents",
14951
+ "conversations",
14952
+ "members",
14953
+ "storage"
14954
+ ];
14955
+ var DEFAULT_PROJECTS_LIST_LABELS = {
14956
+ get title() {
14957
+ return getEntityLabel("PROJECT", "PLURAL");
14958
+ },
14959
+ get description() {
14960
+ return `Every ${entityNoun("PROJECT")}: its client, stage, documents and the work on it.`;
14961
+ },
14962
+ get searchPlaceholder() {
14963
+ return `Search ${entityNoun("PROJECT", "PLURAL")} and workspaces\u2026`;
14964
+ },
14965
+ columns: {
14966
+ get name() {
14967
+ return getEntityLabel("PROJECT");
14968
+ },
14969
+ client: "Client",
14970
+ stage: "Stage",
14971
+ documents: "Documents",
14972
+ conversations: "Threads",
14973
+ members: "Team",
14974
+ storage: "Storage"
14975
+ },
14976
+ opened: "opened",
14977
+ get loadingTitle() {
14978
+ return `Loading ${entityNoun("PROJECT", "PLURAL")}\u2026`;
14979
+ },
14980
+ get loadingDescription() {
14981
+ return `Fetching your ${entityNoun("PROJECT", "PLURAL")}.`;
14982
+ },
14983
+ get emptyTitle() {
14984
+ return `No ${entityNoun("PROJECT", "PLURAL")} yet`;
14985
+ }
14986
+ };
14987
+ function formatStorageGb(gb3) {
14988
+ if (gb3 <= 0) return "\u2014";
14989
+ if (gb3 < 0.1) return `${Math.round(gb3 * 1024)} MB`;
14990
+ return `${gb3.toFixed(2)} GB`;
14991
+ }
14992
+ function ProjectsListPage({
14993
+ labels: given,
14994
+ columns: shown = DEFAULT_PROJECT_LIST_COLUMNS,
14995
+ actions,
14996
+ testId = "projects"
14997
+ }) {
14998
+ const labels = {
14999
+ ...DEFAULT_PROJECTS_LIST_LABELS,
15000
+ ...given,
15001
+ columns: { ...DEFAULT_PROJECTS_LIST_LABELS.columns, ...given?.columns }
15002
+ };
15003
+ const { openProject } = useBlocksEnvironment();
15004
+ const [search, setSearch] = useState("");
15005
+ const { projects, isLoading } = useProjectSummaries();
15006
+ const rows = useMemo(() => {
15007
+ const q = search.trim().toLowerCase();
15008
+ if (!q) return projects;
15009
+ return projects.filter(
15010
+ (p) => p.name.toLowerCase().includes(q) || p.workspaces.some((w) => w.name.toLowerCase().includes(q))
15011
+ );
15012
+ }, [search, projects]);
15013
+ const all = {
15014
+ name: {
15015
+ key: "name",
15016
+ header: labels.columns.name,
15017
+ render: (p) => /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
15018
+ /* @__PURE__ */ jsx("p", { className: "max-w-[22rem] truncate font-medium text-foreground", children: p.name }),
15019
+ /* @__PURE__ */ jsxs("p", { className: "truncate text-xs text-muted-foreground", children: [
15020
+ /* @__PURE__ */ jsx("span", { className: "font-mono", children: p.clientRef || p.id }),
15021
+ " \xB7 ",
15022
+ labels.opened,
15023
+ " ",
15024
+ fmtDate(p.createdAt)
15025
+ ] })
15026
+ ] })
15027
+ },
15028
+ client: {
15029
+ key: "client",
15030
+ header: labels.columns.client,
15031
+ render: (p) => /* @__PURE__ */ jsx("span", { className: "text-sm text-foreground", children: p.client || "\u2014" })
15032
+ },
15033
+ stage: {
15034
+ key: "stage",
15035
+ header: labels.columns.stage,
15036
+ render: (p) => p.stage ? /* @__PURE__ */ jsx(Badge, { variant: "secondary", children: p.stage }) : /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "\u2014" })
15037
+ },
15038
+ documents: {
15039
+ key: "documents",
15040
+ header: labels.columns.documents,
15041
+ align: "right",
15042
+ render: (p) => /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: p.documentCount.toLocaleString() })
15043
+ },
15044
+ conversations: {
15045
+ key: "conversations",
15046
+ header: labels.columns.conversations,
15047
+ align: "right",
15048
+ render: (p) => /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: p.conversationCount.toLocaleString() })
15049
+ },
15050
+ members: {
15051
+ key: "team",
15052
+ header: labels.columns.members,
15053
+ render: (p) => p.memberCount ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 text-sm text-foreground", children: [
15054
+ /* @__PURE__ */ jsx(Users, { className: "size-3.5 text-muted-foreground" }),
15055
+ p.memberCount
15056
+ ] }) : /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "\u2014" })
15057
+ },
15058
+ storage: {
15059
+ key: "storage",
15060
+ header: labels.columns.storage,
15061
+ align: "right",
15062
+ render: (p) => /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: formatStorageGb(p.storageUsedGb) })
15063
+ }
15064
+ };
15065
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-6", "data-testid": `page-${testId}`, children: [
15066
+ /* @__PURE__ */ jsx(
15067
+ PageHeader,
15068
+ {
15069
+ eyebrow: labels.eyebrow,
15070
+ title: labels.title,
15071
+ description: labels.description,
15072
+ actions
15073
+ }
15074
+ ),
15075
+ /* @__PURE__ */ jsx(
15076
+ Toolbar,
15077
+ {
15078
+ search,
15079
+ onSearch: setSearch,
15080
+ searchPlaceholder: labels.searchPlaceholder,
15081
+ testId: `${testId}-toolbar`
15082
+ }
15083
+ ),
15084
+ /* @__PURE__ */ jsx(
15085
+ DataTable,
15086
+ {
15087
+ area: testId,
15088
+ columns: shown.map((c) => all[c]),
15089
+ rows,
15090
+ getRowId: (p) => p.id,
15091
+ onRowClick: (p) => openProject(p.id),
15092
+ emptyTitle: isLoading ? labels.loadingTitle : labels.emptyTitle,
15093
+ emptyDescription: isLoading ? labels.loadingDescription : labels.emptyDescription
15094
+ }
15095
+ )
15096
+ ] });
15097
+ }
14778
15098
  var PROJECTS_BASE_TAB_ID = "projects";
14779
15099
  var isPaid = (p) => p.subscription === "active" || p.subscription === "past_due";
14780
15100
  function useLocalProjectTabs() {
@@ -14794,6 +15114,13 @@ function useLocalProjectTabs() {
14794
15114
  };
14795
15115
  }
14796
15116
  function ConnectedProjectsPanel({
15117
+ layout = "panel",
15118
+ page,
15119
+ ...panel
15120
+ }) {
15121
+ return layout === "page" ? /* @__PURE__ */ jsx(ProjectsListPage, { ...page }) : /* @__PURE__ */ jsx(ProjectsPanel, { ...panel });
15122
+ }
15123
+ function ProjectsPanel({
14797
15124
  tabs: hostTabs,
14798
15125
  projectStorage,
14799
15126
  footer,
@@ -14828,10 +15155,10 @@ function ConnectedProjectsPanel({
14828
15155
  },
14829
15156
  ...tabs.openProjectIds.map((id) => ({
14830
15157
  id,
14831
- label: projects?.find((p) => p.external_id === id)?.name ?? "Project",
15158
+ label: projects?.find((p) => p.external_id === id)?.name ?? getEntityLabel("PROJECT"),
14832
15159
  icon: /* @__PURE__ */ jsx(EntityIcon, { entityType: "PROJECT" }),
14833
15160
  onClose: () => tabs.onClose(id),
14834
- closeTooltip: "Close project"
15161
+ closeTooltip: `Close ${entityNoun("PROJECT")}`
14835
15162
  }))
14836
15163
  ],
14837
15164
  [ownedCount, tabs, projects]
@@ -14847,7 +15174,7 @@ function ConnectedProjectsPanel({
14847
15174
  afterTabs: (isCompact) => /* @__PURE__ */ jsx(
14848
15175
  PanelAddButton,
14849
15176
  {
14850
- label: "New project",
15177
+ label: `New ${entityNoun("PROJECT")}`,
14851
15178
  onClick: () => setNewProjectOpen(true),
14852
15179
  icon: /* @__PURE__ */ jsx(Plus, { className: "size-4" }),
14853
15180
  isCompact,
@@ -14890,110 +15217,12 @@ function ConnectedProjectsPanel({
14890
15217
  {
14891
15218
  open: newProjectOpen,
14892
15219
  onOpenChange: setNewProjectOpen,
14893
- defaultName: `Project ${(projects?.length ?? 0) + 1}`
15220
+ defaultName: `${getEntityLabel("PROJECT")} ${(projects?.length ?? 0) + 1}`
14894
15221
  }
14895
15222
  )
14896
15223
  ] });
14897
15224
  return hostTabs ? panel : /* @__PURE__ */ jsx(ArbiHost, { config: localHost, children: panel });
14898
15225
  }
14899
- function workspaceSummary(w) {
14900
- return {
14901
- id: w.external_id,
14902
- name: w.name,
14903
- description: w.description ?? void 0,
14904
- isPublic: !!w.is_public,
14905
- documentCount: workspaceDocumentCount(w),
14906
- conversationCount: workspaceConversationCount(w),
14907
- memberCount: w.users?.length ?? 0,
14908
- filesMb: w.user_files_mb ?? 0,
14909
- updatedAt: w.updated_at
14910
- };
14911
- }
14912
- function distinctMembers(workspaces) {
14913
- const byId = /* @__PURE__ */ new Map();
14914
- for (const w of workspaces) {
14915
- for (const member of w.users ?? []) {
14916
- const user = member.user;
14917
- const id = user?.external_id;
14918
- if (!id || byId.has(id)) continue;
14919
- const name = [user.given_name, user.family_name].filter(Boolean).join(" ").trim();
14920
- byId.set(id, {
14921
- id,
14922
- name: name || user.email || "Unknown",
14923
- email: user.email ?? "",
14924
- role: member.role ?? "member",
14925
- isAgent: Boolean(member.agent_ext_id) || isAgentAccount(user)
14926
- });
14927
- }
14928
- }
14929
- return [...byId.values()];
14930
- }
14931
- function buildProjectSummaries(projects, workspaces) {
14932
- const byProject = /* @__PURE__ */ new Map();
14933
- for (const w of workspaces ?? []) {
14934
- const id = w.project_ext_id;
14935
- if (!id) continue;
14936
- byProject.set(id, [...byProject.get(id) ?? [], w]);
14937
- }
14938
- const summaries = (projects ?? []).map((p) => {
14939
- const own = byProject.get(p.external_id) ?? [];
14940
- const storage = p.quotas?.storage_gb;
14941
- const aiUsage = p.quotas?.ai_usage;
14942
- const stats = workspaceGroupStats(own);
14943
- return {
14944
- id: p.external_id,
14945
- name: p.name,
14946
- createdAt: p.created_at,
14947
- subscription: p.subscription ?? "none",
14948
- workspaces: own.map(workspaceSummary),
14949
- workspaceCount: own.length,
14950
- documentCount: stats.documents,
14951
- conversationCount: stats.conversations,
14952
- members: distinctMembers(own),
14953
- memberCount: stats.members,
14954
- filesMb: own.reduce((sum, w) => sum + (w.user_files_mb ?? 0), 0),
14955
- storageUsedGb: storage?.used ?? 0,
14956
- storageLimitGb: storage?.limit ?? 0,
14957
- aiUsageUsed: aiUsage?.used ?? 0,
14958
- aiUsageLimit: aiUsage?.limit ?? 0,
14959
- client: p.client ?? null,
14960
- clientRef: p.client_ref ?? null,
14961
- stage: p.stage ?? null,
14962
- leadUser: p.lead_user ?? null,
14963
- budget: p.budget ?? null,
14964
- fields: p.fields ?? {}
14965
- };
14966
- });
14967
- const work = (s) => s.documentCount + s.conversationCount;
14968
- return summaries.sort((a, b) => work(b) - work(a));
14969
- }
14970
- function useProjectSummaries() {
14971
- const projects = useProjects();
14972
- const workspaces = useWorkspaces();
14973
- const summaries = useMemo(
14974
- () => buildProjectSummaries(
14975
- projects.data,
14976
- workspaces.data
14977
- ),
14978
- [projects.data, workspaces.data]
14979
- );
14980
- return {
14981
- projects: summaries,
14982
- isLoading: projects.isLoading || workspaces.isLoading,
14983
- isError: projects.isError || workspaces.isError,
14984
- error: projects.error ?? workspaces.error
14985
- };
14986
- }
14987
- function useProjectSummary(projectId) {
14988
- const { projects, isLoading, isError } = useProjectSummaries();
14989
- const project = useMemo(() => projects.find((p) => p.id === projectId), [projects, projectId]);
14990
- const usage = useProjectUsage(projectId, 0, { enabled: !!projectId });
14991
- return { project, usage: usage.data, usageLoading: usage.isLoading, isLoading, isError };
14992
- }
14993
- function primaryProjectWorkspace(project) {
14994
- const work = (w) => w.documentCount + w.conversationCount;
14995
- return [...project.workspaces].sort((a, b) => work(b) - work(a))[0];
14996
- }
14997
15226
  function RowsEditor({
14998
15227
  label,
14999
15228
  rows,
@@ -16727,7 +16956,7 @@ function MailComposerForm({
16727
16956
  "label",
16728
16957
  {
16729
16958
  className: "flex items-center gap-1 text-xs text-muted-foreground",
16730
- title: "ARBI's work on this email is billed to this project",
16959
+ title: `ARBI's work on this email is billed to this ${entityNoun("PROJECT")}`,
16731
16960
  children: [
16732
16961
  "Billed to",
16733
16962
  /* @__PURE__ */ jsx(
@@ -35894,16 +36123,74 @@ async function backUpOnSignup({
35894
36123
  }
35895
36124
  }
35896
36125
 
35897
- // src/connection/auth/useLoginActions.ts
36126
+ // src/connection/auth/sso-name.ts
36127
+ var clean = (value) => value?.trim() ?? "";
36128
+ function resolveSsoName(profile, preferred = {}, emailFallback) {
36129
+ const fullName = clean(profile.name);
36130
+ let given = clean(preferred.given_name) || clean(profile.given_name);
36131
+ let family = clean(preferred.family_name) || clean(profile.family_name);
36132
+ if (!given && fullName) {
36133
+ const surnameAtEnd = family && fullName.length > family.length && fullName.toLowerCase().endsWith(family.toLowerCase());
36134
+ given = surnameAtEnd ? fullName.slice(0, fullName.length - family.length).trim() : fullName.split(/\s+/)[0];
36135
+ }
36136
+ if (!family && given && fullName.toLowerCase().startsWith(given.toLowerCase())) {
36137
+ family = fullName.slice(given.length).trim();
36138
+ }
36139
+ if (!given && emailFallback) given = emailFallback.split("@")[0];
36140
+ return { given_name: given, family_name: family };
36141
+ }
36142
+
36143
+ // src/connection/auth/sso-sign-in.ts
36144
+ function ssoAccountStatus(arbi, token, user) {
36145
+ return arbi.sso.status({ token, email: user.email, picture: user.picture });
36146
+ }
36147
+ async function completeSsoSignIn(arbi, { token, user, status, password, saveRecoveryKey = true }) {
36148
+ const email = user.email;
36149
+ if (status.status === "new_user") {
36150
+ const { given_name: firstName2, family_name: lastName } = resolveSsoName(user, status, email);
36151
+ const { signingPrivateKey } = await arbi.sso.register({
36152
+ token,
36153
+ email,
36154
+ password,
36155
+ firstName: firstName2,
36156
+ lastName,
36157
+ picture: user.picture
36158
+ });
36159
+ await backUpOnSignup({
36160
+ email,
36161
+ password,
36162
+ signingPrivateKey,
36163
+ saveRecoveryKey,
36164
+ auth0Sub: user.sub
36165
+ });
36166
+ const login2 = await arbi.sso.login({
36167
+ token,
36168
+ email,
36169
+ password,
36170
+ profile: { ...resolveSsoName(user, status), picture: user.picture ?? null }
36171
+ });
36172
+ return { login: login2, registered: true, linked: false };
36173
+ }
36174
+ const linked = status.status === "local_exists";
36175
+ const signIn = linked ? arbi.sso.link : arbi.sso.login;
36176
+ const login = await signIn({ token, email, password });
36177
+ return { login: login ?? void 0, registered: false, linked };
36178
+ }
35898
36179
  var BAD_CREDENTIALS = "This username/password combination is not valid. Please double-check your credentials and try again.";
35899
36180
  function useLoginActions({
35900
36181
  formState,
35901
- formActions
36182
+ formActions,
36183
+ onError
35902
36184
  }) {
35903
36185
  const arbi = useArbi();
35904
36186
  const signInLayer = useOptionalConnection();
35905
36187
  const sso = useSsoSignIn();
35906
- const { notify: notify17 } = useBlocksEnvironment();
36188
+ const environment = useBlocksEnvironment();
36189
+ const environmentNotify = environment.notify;
36190
+ const notify17 = useCallback(
36191
+ (...args) => args[1] === "error" && onError && typeof args[0] === "string" ? onError(args[0]) : environmentNotify(...args),
36192
+ [environmentNotify, onError]
36193
+ );
35907
36194
  const { passwordRules, onRegistered, onUnlockedOffline } = useAuthPages();
35908
36195
  const [isAuthenticating, setIsAuthenticating] = useState(false);
35909
36196
  const [isRequestingCode, setIsRequestingCode] = useState(false);
@@ -35911,7 +36198,7 @@ function useLoginActions({
35911
36198
  email,
35912
36199
  password,
35913
36200
  confirmPassword,
35914
- firstName,
36201
+ firstName: firstName2,
35915
36202
  lastName,
35916
36203
  verificationCode,
35917
36204
  cooldownSeconds
@@ -35990,6 +36277,7 @@ function useLoginActions({
35990
36277
  try {
35991
36278
  const login = await arbi.login(loginEmail, loginPassword);
35992
36279
  if (opts?.isFreshRegistration) onRegistered?.(login);
36280
+ return login;
35993
36281
  } catch (error) {
35994
36282
  setIsAuthenticating(false);
35995
36283
  console.error("Login error:", error);
@@ -36015,7 +36303,7 @@ function useLoginActions({
36015
36303
  const handleRegister = useCallback(
36016
36304
  async (saveRecoveryKey = true) => {
36017
36305
  arbi.session?.setSsoMode(false);
36018
- if (!password || !confirmPassword || !firstName || !lastName || !verificationCode) {
36306
+ if (!password || !confirmPassword || !firstName2 || !lastName || !verificationCode) {
36019
36307
  notify17("Please fill in all required fields.", "error");
36020
36308
  return;
36021
36309
  }
@@ -36035,7 +36323,7 @@ function useLoginActions({
36035
36323
  email,
36036
36324
  password,
36037
36325
  verificationCode: verificationCode.trim(),
36038
- firstName,
36326
+ firstName: firstName2,
36039
36327
  lastName
36040
36328
  });
36041
36329
  await backUpOnSignup({ email, password, signingPrivateKey, saveRecoveryKey });
@@ -36051,7 +36339,7 @@ function useLoginActions({
36051
36339
  email,
36052
36340
  password,
36053
36341
  confirmPassword,
36054
- firstName,
36342
+ firstName2,
36055
36343
  lastName,
36056
36344
  verificationCode,
36057
36345
  validateEmailWithError,
@@ -36075,7 +36363,7 @@ function useLoginForm() {
36075
36363
  const [email, setEmail] = useState("");
36076
36364
  const [password, setPassword] = useState("");
36077
36365
  const [confirmPassword, setConfirmPassword] = useState("");
36078
- const [firstName, setFirstName] = useState("");
36366
+ const [firstName2, setFirstName] = useState("");
36079
36367
  const [lastName, setLastName] = useState("");
36080
36368
  const [verificationCode, setVerificationCode] = useState("");
36081
36369
  const [verificationSent, setVerificationSent] = useState(false);
@@ -36211,7 +36499,7 @@ function useLoginForm() {
36211
36499
  email,
36212
36500
  password,
36213
36501
  confirmPassword,
36214
- firstName,
36502
+ firstName: firstName2,
36215
36503
  lastName,
36216
36504
  verificationCode,
36217
36505
  verificationSent,
@@ -36247,36 +36535,242 @@ function useLoginForm() {
36247
36535
  };
36248
36536
  return { ...state, ...actions };
36249
36537
  }
36250
- function useRegisterSubmitState(isRegistering, isPending, password, confirmPassword, email, firstName, lastName, verificationCode, isPasswordValid) {
36538
+ function useRegisterSubmitState(isRegistering, isPending, password, confirmPassword, email, firstName2, lastName, verificationCode, isPasswordValid) {
36251
36539
  const isDisabled = useMemo(() => {
36252
36540
  if (!isRegistering) return false;
36253
- return isPending || !isPasswordValid(password) || password !== confirmPassword || !email || !firstName || !lastName || !verificationCode;
36541
+ return isPending || !isPasswordValid(password) || password !== confirmPassword || !email || !firstName2 || !lastName || !verificationCode;
36254
36542
  }, [
36255
36543
  isRegistering,
36256
36544
  isPending,
36257
36545
  password,
36258
36546
  confirmPassword,
36259
36547
  email,
36260
- firstName,
36548
+ firstName2,
36261
36549
  lastName,
36262
36550
  verificationCode,
36263
36551
  isPasswordValid
36264
36552
  ]);
36265
36553
  const isDefault = useMemo(() => {
36266
36554
  if (!isRegistering) return false;
36267
- return email && password && confirmPassword && firstName && lastName && verificationCode && isPasswordValid(password) && password === confirmPassword;
36555
+ return email && password && confirmPassword && firstName2 && lastName && verificationCode && isPasswordValid(password) && password === confirmPassword;
36268
36556
  }, [
36269
36557
  isRegistering,
36270
36558
  email,
36271
36559
  password,
36272
36560
  confirmPassword,
36273
- firstName,
36561
+ firstName2,
36274
36562
  lastName,
36275
36563
  verificationCode,
36276
36564
  isPasswordValid
36277
36565
  ]);
36278
36566
  return { isDisabled, isDefault };
36279
36567
  }
36568
+ var firstName = (user, fallback) => user?.given_name || fallback.split("@")[0];
36569
+ function CompactLogin({
36570
+ onSsoSignIn,
36571
+ onSignedIn,
36572
+ appName = "ARBI",
36573
+ ssoName = appName
36574
+ }) {
36575
+ const arbi = useArbi();
36576
+ const auth = useAuthPages();
36577
+ const { notify: notify17 } = useBlocksEnvironment();
36578
+ const isSsoOnly = !!auth.ssoOnly;
36579
+ const [error, setError] = useState(null);
36580
+ const formState = useLoginForm();
36581
+ const { email, password, setEmail, setPassword } = formState;
36582
+ const { isAuthenticating, handleLocalLogin } = useLoginActions({
36583
+ formState,
36584
+ formActions: formState,
36585
+ onError: setError
36586
+ });
36587
+ const [sso, setSso] = useState(null);
36588
+ const [masterPassword, setMasterPassword] = useState("");
36589
+ const signInLocally = async (e) => {
36590
+ e.preventDefault();
36591
+ setError(null);
36592
+ const login = await handleLocalLogin();
36593
+ if (login) onSignedIn?.(firstName(login.response?.user, email));
36594
+ };
36595
+ const finishSso = async () => {
36596
+ if (!sso?.user.email) {
36597
+ setError("User email not available");
36598
+ return;
36599
+ }
36600
+ try {
36601
+ const status = await ssoAccountStatus(arbi, sso.accessToken, sso.user);
36602
+ const { login } = await completeSsoSignIn(arbi, {
36603
+ token: sso.accessToken,
36604
+ user: sso.user,
36605
+ status,
36606
+ password: masterPassword
36607
+ });
36608
+ const name = login?.response?.user.given_name ?? sso.user.given_name ?? sso.user.name;
36609
+ setError(null);
36610
+ setSso(null);
36611
+ setMasterPassword("");
36612
+ const shown = name ?? sso.user.email.split("@")[0];
36613
+ notify17(`Welcome, ${shown}!`, "success");
36614
+ onSignedIn?.(shown);
36615
+ } catch (err) {
36616
+ console.error("[SSO] Error during authentication:", err);
36617
+ setError(parseAuthError(err, { defaultMessage: "Authentication failed. Please try again." }));
36618
+ }
36619
+ };
36620
+ const startSso = async () => {
36621
+ if (!onSsoSignIn) return;
36622
+ try {
36623
+ const result = await onSsoSignIn();
36624
+ if (result) setSso(result);
36625
+ } catch (err) {
36626
+ setError(err instanceof Error ? err.message : "Authentication failed. Please try again.");
36627
+ }
36628
+ };
36629
+ const cancelSso = () => {
36630
+ setSso(null);
36631
+ setMasterPassword("");
36632
+ setError(null);
36633
+ };
36634
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-4", "data-testid": "embedded-auth", children: [
36635
+ error && /* @__PURE__ */ jsx(
36636
+ "div",
36637
+ {
36638
+ className: "bg-destructive/10 text-destructive p-3 rounded-md",
36639
+ "data-testid": "embedded-auth-error",
36640
+ children: /* @__PURE__ */ jsx("p", { className: "text-sm", children: error })
36641
+ }
36642
+ ),
36643
+ sso ? /* @__PURE__ */ jsxs(
36644
+ "form",
36645
+ {
36646
+ onSubmit: (e) => {
36647
+ e.preventDefault();
36648
+ if (masterPassword) void finishSso();
36649
+ },
36650
+ className: "space-y-3",
36651
+ children: [
36652
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
36653
+ "Enter your ",
36654
+ appName,
36655
+ " ",
36656
+ /* @__PURE__ */ jsx("strong", { children: "master password" }),
36657
+ " \u2014 the encryption passphrase you set when you first registered, not your ",
36658
+ ssoName,
36659
+ " sign-in password."
36660
+ ] }),
36661
+ /* @__PURE__ */ jsx(
36662
+ Input,
36663
+ {
36664
+ type: "password",
36665
+ placeholder: "Enter master password",
36666
+ value: masterPassword,
36667
+ onChange: (e) => setMasterPassword(e.target.value),
36668
+ autoFocus: true,
36669
+ "data-testid": "embedded-auth-password-input"
36670
+ }
36671
+ ),
36672
+ /* @__PURE__ */ jsx(
36673
+ Button,
36674
+ {
36675
+ type: "submit",
36676
+ className: "w-full",
36677
+ disabled: !masterPassword,
36678
+ "data-testid": "embedded-auth-continue-button",
36679
+ children: "Continue"
36680
+ }
36681
+ ),
36682
+ /* @__PURE__ */ jsx(
36683
+ Button,
36684
+ {
36685
+ type: "button",
36686
+ variant: "outline",
36687
+ className: "w-full",
36688
+ onClick: cancelSso,
36689
+ "data-testid": "embedded-auth-cancel-button",
36690
+ children: "Cancel"
36691
+ }
36692
+ )
36693
+ ]
36694
+ }
36695
+ ) : isSsoOnly ? /* @__PURE__ */ jsxs(Fragment, { children: [
36696
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Please sign in with your organization account." }),
36697
+ /* @__PURE__ */ jsxs(
36698
+ Button,
36699
+ {
36700
+ onClick: () => void startSso(),
36701
+ className: "w-full",
36702
+ "data-testid": "embedded-auth-sso-button",
36703
+ children: [
36704
+ /* @__PURE__ */ jsx(LogIn, { className: "mr-2 h-4 w-4" }),
36705
+ "Sign in with ",
36706
+ ssoName
36707
+ ]
36708
+ }
36709
+ )
36710
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
36711
+ /* @__PURE__ */ jsxs("form", { onSubmit: (e) => void signInLocally(e), className: "space-y-3", children: [
36712
+ /* @__PURE__ */ jsx(
36713
+ Input,
36714
+ {
36715
+ type: "email",
36716
+ placeholder: "Email",
36717
+ value: email,
36718
+ onChange: (e) => setEmail(e.target.value),
36719
+ required: true,
36720
+ disabled: isAuthenticating,
36721
+ "data-testid": "embedded-auth-email-input"
36722
+ }
36723
+ ),
36724
+ /* @__PURE__ */ jsx(
36725
+ Input,
36726
+ {
36727
+ type: "password",
36728
+ placeholder: "Password",
36729
+ value: password,
36730
+ onChange: (e) => setPassword(e.target.value),
36731
+ required: true,
36732
+ disabled: isAuthenticating,
36733
+ "data-testid": "embedded-auth-password-input"
36734
+ }
36735
+ ),
36736
+ /* @__PURE__ */ jsx(
36737
+ Button,
36738
+ {
36739
+ type: "submit",
36740
+ className: "w-full",
36741
+ disabled: isAuthenticating,
36742
+ "data-testid": "embedded-auth-signin-button",
36743
+ children: isAuthenticating ? /* @__PURE__ */ jsxs(Fragment, { children: [
36744
+ /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
36745
+ "Signing in..."
36746
+ ] }) : "Sign In"
36747
+ }
36748
+ )
36749
+ ] }),
36750
+ onSsoSignIn && /* @__PURE__ */ jsxs(Fragment, { children: [
36751
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
36752
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ jsx("span", { className: "w-full border-t" }) }),
36753
+ /* @__PURE__ */ jsx("div", { className: "relative flex justify-center text-sm uppercase", children: /* @__PURE__ */ jsx("span", { className: "bg-background px-2 text-muted-foreground", children: "Or" }) })
36754
+ ] }),
36755
+ /* @__PURE__ */ jsxs(
36756
+ Button,
36757
+ {
36758
+ onClick: () => void startSso(),
36759
+ className: "w-full",
36760
+ variant: "outline",
36761
+ "data-testid": "embedded-auth-sso-option-button",
36762
+ children: [
36763
+ /* @__PURE__ */ jsx(LogIn, { className: "mr-2 h-4 w-4" }),
36764
+ "Sign in with ",
36765
+ ssoName,
36766
+ " (SSO)"
36767
+ ]
36768
+ }
36769
+ )
36770
+ ] })
36771
+ ] })
36772
+ ] });
36773
+ }
36280
36774
  function useSsoVerificationRedirect() {
36281
36775
  const sso = useSsoSignIn();
36282
36776
  const { notify: notify17 } = useBlocksEnvironment();
@@ -36314,7 +36808,13 @@ function warmSodium() {
36314
36808
  if (typeof window.requestIdleCallback === "function") window.requestIdleCallback(run);
36315
36809
  else window.setTimeout(run, 200);
36316
36810
  }
36317
- function ConnectedLoginPage() {
36811
+ function ConnectedLoginPage({
36812
+ layout = "page",
36813
+ ...compact
36814
+ } = {}) {
36815
+ return layout === "compact" ? /* @__PURE__ */ jsx(CompactLogin, { ...compact }) : /* @__PURE__ */ jsx(LoginPage, {});
36816
+ }
36817
+ function LoginPage() {
36318
36818
  const sso = useSsoSignIn();
36319
36819
  const auth = useAuthPages();
36320
36820
  const { notify: notify17 } = useBlocksEnvironment();
@@ -36329,7 +36829,7 @@ function ConnectedLoginPage() {
36329
36829
  email,
36330
36830
  password,
36331
36831
  confirmPassword,
36332
- firstName,
36832
+ firstName: firstName2,
36333
36833
  lastName,
36334
36834
  verificationCode,
36335
36835
  verificationSent,
@@ -36370,7 +36870,7 @@ function ConnectedLoginPage() {
36370
36870
  password,
36371
36871
  confirmPassword,
36372
36872
  email,
36373
- firstName,
36873
+ firstName2,
36374
36874
  lastName,
36375
36875
  verificationCode,
36376
36876
  passwordRules.isValid
@@ -36624,7 +37124,7 @@ function ConnectedLoginPage() {
36624
37124
  {
36625
37125
  type: "text",
36626
37126
  placeholder: "",
36627
- value: firstName,
37127
+ value: firstName2,
36628
37128
  onChange: (e) => setFirstName(e.target.value),
36629
37129
  "data-testid": "firstname-input",
36630
37130
  name: "firstName",
@@ -36803,6 +37303,46 @@ function ConnectedLoginPage() {
36803
37303
  }
36804
37304
  );
36805
37305
  }
37306
+
37307
+ // src/connection/auth/sso-popup.ts
37308
+ function openSsoPopup(url, { features = "width=600,height=700" } = {}) {
37309
+ return new Promise((resolve, reject) => {
37310
+ const opened = window.open(url, "auth", features);
37311
+ if (!opened) {
37312
+ resolve(null);
37313
+ return;
37314
+ }
37315
+ const popup = opened;
37316
+ const closedPoll = setInterval(() => {
37317
+ if (popup.closed) {
37318
+ done();
37319
+ resolve(null);
37320
+ }
37321
+ }, 500);
37322
+ const done = () => {
37323
+ window.removeEventListener("message", onMessage);
37324
+ clearInterval(closedPoll);
37325
+ };
37326
+ function onMessage(event) {
37327
+ if (event.origin !== window.location.origin) return;
37328
+ const data = event.data;
37329
+ if (data?.error) {
37330
+ done();
37331
+ reject(new Error(data.error));
37332
+ return;
37333
+ }
37334
+ if (!data?.accessToken) return;
37335
+ done();
37336
+ if (!popup.closed) popup.close();
37337
+ if (!data.user) {
37338
+ reject(new Error("Invalid authentication response"));
37339
+ return;
37340
+ }
37341
+ resolve({ accessToken: data.accessToken, user: data.user });
37342
+ }
37343
+ window.addEventListener("message", onMessage);
37344
+ });
37345
+ }
36806
37346
  var MAX_RESEND_WARNING_THRESHOLD = 3;
36807
37347
  var MAX_RESEND_BLOCK_THRESHOLD = 6;
36808
37348
  var RATE_LIMIT_COOLDOWN_MS = 6e4;
@@ -36876,23 +37416,6 @@ function SsoResendVerificationButton({
36876
37416
  }
36877
37417
  ) : /* @__PURE__ */ jsx(Fragment, {});
36878
37418
  }
36879
-
36880
- // src/connection/auth/sso-name.ts
36881
- var clean = (value) => value?.trim() ?? "";
36882
- function resolveSsoName(profile, preferred = {}, emailFallback) {
36883
- const fullName = clean(profile.name);
36884
- let given = clean(preferred.given_name) || clean(profile.given_name);
36885
- let family = clean(preferred.family_name) || clean(profile.family_name);
36886
- if (!given && fullName) {
36887
- const surnameAtEnd = family && fullName.length > family.length && fullName.toLowerCase().endsWith(family.toLowerCase());
36888
- given = surnameAtEnd ? fullName.slice(0, fullName.length - family.length).trim() : fullName.split(/\s+/)[0];
36889
- }
36890
- if (!family && given && fullName.toLowerCase().startsWith(given.toLowerCase())) {
36891
- family = fullName.slice(given.length).trim();
36892
- }
36893
- if (!given && emailFallback) given = emailFallback.split("@")[0];
36894
- return { given_name: given, family_name: family };
36895
- }
36896
37419
  var NO_RECOVERY_KEY_WARNING2 = "Without your password or a recovery key, we cannot recover your account or data.";
36897
37420
  function ConnectedSsoCallback() {
36898
37421
  const sso = useSsoSignIn();
@@ -37082,11 +37605,7 @@ function ConnectedSsoCallback() {
37082
37605
  setIsCheckingStatus(true);
37083
37606
  try {
37084
37607
  console.info("[SSO] Checking user status...");
37085
- const response = await arbi.sso.status({
37086
- token: accessToken,
37087
- email: user.email,
37088
- picture: user.picture
37089
- });
37608
+ const response = await ssoAccountStatus(arbi, accessToken, user);
37090
37609
  console.info("[SSO] User status:", response.status);
37091
37610
  setSsoStatus(response);
37092
37611
  } catch (error2) {
@@ -37130,40 +37649,18 @@ function ConnectedSsoCallback() {
37130
37649
  setIsSubmitting(true);
37131
37650
  setError(null);
37132
37651
  try {
37133
- const email = user.email;
37134
- if (ssoStatus.status === "new_user") {
37135
- const { given_name: firstName, family_name: lastName } = resolveSsoName(
37136
- user,
37137
- ssoStatus,
37138
- email
37139
- );
37140
- const { signingPrivateKey } = await arbi.sso.register({
37141
- token: accessToken,
37142
- email,
37143
- password,
37144
- firstName,
37145
- lastName,
37146
- picture: user.picture
37147
- });
37148
- await backUpOnSignup({
37149
- email,
37150
- password,
37151
- signingPrivateKey,
37152
- saveRecoveryKey,
37153
- auth0Sub: user.sub
37154
- });
37155
- const login = await arbi.sso.login({
37156
- token: accessToken,
37157
- email,
37158
- password,
37159
- profile: { ...resolveSsoName(user, ssoStatus), picture: user.picture ?? null }
37160
- });
37652
+ const { login, registered, linked } = await completeSsoSignIn(arbi, {
37653
+ token: accessToken,
37654
+ user,
37655
+ status: ssoStatus,
37656
+ password,
37657
+ saveRecoveryKey
37658
+ });
37659
+ if (registered && login) {
37161
37660
  auth.onRegistered?.(login);
37162
37661
  return;
37163
37662
  }
37164
- const signIn = ssoStatus.status === "local_exists" ? arbi.sso.link : arbi.sso.login;
37165
- await signIn({ token: accessToken, email, password });
37166
- if (ssoStatus.status === "local_exists") {
37663
+ if (linked) {
37167
37664
  notify17("Your local account has been linked to SSO", "success");
37168
37665
  }
37169
37666
  } catch (err) {
@@ -37909,7 +38406,7 @@ function ConnectedAccountAccessBadge() {
37909
38406
  "Temporary access to shared workspaces. Ask an owner to renew access after it expires."
37910
38407
  ] : user.user_type === "manager" ? [
37911
38408
  "Account manager",
37912
- "You can manage project billing and usage. Workspace access is managed by workspace owners."
38409
+ `You can manage ${entityNoun("PROJECT")} billing and usage. Workspace access is managed by workspace owners.`
37913
38410
  ] : user.user_type === "blocked" ? [
37914
38411
  "Access restricted",
37915
38412
  "Contact your deployment administrator about your account access."
@@ -37941,6 +38438,6 @@ function ConnectedAccountAccessBadge() {
37941
38438
  ] });
37942
38439
  }
37943
38440
 
37944
- export { AddAddonDialog, AddFromAccountsButton, AgentBarShell, AgentControlBar, AgentSteps, AnswerTable, AskAgainContext, BACKFILL_OPTIONS, BULK_REPROCESS_LIMIT, BillingProjectEntity, ChangePlanDialog, ChatAttachmentList, ConnectedAccountAccessBadge, ConnectedAccountSettings, ConnectedAddContacts, ConnectedAgentChat, ConnectedAgentChatPanel, ConnectedAgentConfigForm, ConnectedAgentCreator, ConnectedAiReview, ConnectedAppsSettings, ConnectedAuthorizeAgent, ConnectedBranchControls, ConnectedBulkTagEditor, ConnectedCalendar, ConnectedChatThread, ConnectedCitationRenderer, ConnectedCompactConversation, ConnectedConfigForm, ConnectedContactCardForm, ConnectedContactToggle, ConnectedContactsDirectory, ConnectedConversation, ConnectedConversationDocumentPicker, ConnectedConversationEmpty, ConnectedConversationStart, ConnectedDangerZone, ConnectedDeploymentStorage, ConnectedDeveloperConfig, ConnectedDriveSyncDialog, ConnectedExportDialog, ConnectedExportPanel, ConnectedFactsPage, ConnectedFieldsEditor, ConnectedFieldsManager, ConnectedFilesBulkActions, ConnectedFilesExplorer, ConnectedFilesPage, ConnectedForgotPassword, ConnectedGrantWorkspaceAccessDialog, ConnectedGroupMembers, ConnectedIdentityVerification, ConnectedLoginPage, ConnectedLogoutDialog, ConnectedMailAccounts, ConnectedMailComposer, ConnectedMailInviteCard, ConnectedMailMessage, ConnectedMailSettings, ConnectedMailSetup, ConnectedMailbox, ConnectedMailboxSyncDialog, ConnectedMessage, ConnectedMessageArea, ConnectedMessageList, ConnectedMessenger, ConnectedModelSelector, ConnectedMoveToFolder, ConnectedNewThreadDialog, ConnectedNotificationCenter, ConnectedNotificationPreferences, ConnectedOAuthConsentPage, ConnectedPasswordChangeDialog, ConnectedPremiumModels, ConnectedPrivacySettings, ConnectedProfileCard, ConnectedProjectEntity, ConnectedProjectStorage, ConnectedProjectsPanel, ConnectedPublicBooking, ConnectedQuotaDialog, ConnectedRecentlyDeletedButton, ConnectedRecoveryKeyDialog, ConnectedRequestWorkspaceAccess, ConnectedRequireVerified, ConnectedSearchPage, ConnectedSecuritySection, ConnectedSessionsRow, ConnectedSettingsPage, ConnectedSharePointAdminConsentPage, ConnectedSharedFilesPage, ConnectedSignatureVerifyPage, ConnectedSkillUpload, ConnectedSkillsLibrary, ConnectedSsoCallback, ConnectedStorageProjectCard, ConnectedStorageSettings, ConnectedTagEditorDialog, ConnectedTagEntity, ConnectedTagForm, ConnectedTagTable, ConnectedTagsPage, ConnectedTaskAccessRequest, ConnectedTaskActivityDialog, ConnectedTaskComposer, ConnectedTaskStartDialog, ConnectedThreadFollow, ConnectedThreadLauncher, ConnectedThreadTabs, ConnectedThreadTaskBar, ConnectedThreadsPreview, ConnectedTransferWatcher, ConnectedUpcomingEvents, ConnectedUpload, ConnectedUploadDropzone, ConnectedUserEntity, ConnectedWelcomeDialog, ConnectedWorkflowHistory, ConnectedWorkflowRunner, ConnectedWorkflowStart, ConnectedWorkspaceActivity, ConnectedWorkspaceDashboard, ConnectedWorkspaceEntity, ConnectedWorkspaceList, ConnectedWorkspaceMembers, ConnectedWorkspaceNotificationMenu, ConnectedWorkspaceSettings, ConnectedWorkspaceTrash, ConversationAlert, ConversationComposer2 as ConversationComposer, ConversationEntity, ConversationSendButton, ConversationStatusCell, DEFAULT_CONNECTED_SEARCH_PAGE_LABELS, DEFAULT_CONNECTED_SKILL_UPLOAD_LABELS, DEFAULT_CONNECTED_WORKFLOW_RUNNER_LABELS, DEFAULT_OAUTH_PERMISSIONS, DEFAULT_SEARCH_FIELDS, DEFAULT_SEARCH_ROW_LABELS, DEFAULT_SETTINGS_SECTIONS, DEFAULT_TIMELINE_LABEL_WIDTH, DEFAULT_WORKSPACE_LIST_LABELS, DeveloperFooter, DocumentFolderCell, DocumentLabelsCell, DocumentNameCell, DocumentSharedCell, DocumentStatusGlyph, DocumentSyncGlyph, DocumentUser, DocumentsFilterBarActions, DocumentsUploadButton, EmptyWorkspaceUpload, FACTS_GRID_ID, FILES_PREFS_KEY, FileTooltipContent, ImportVcfButton, ImportVcfSummary, InvoicesModal, LOOK_AGAIN_LABEL, MessageDetailsModal, MessageLiveSeconds, MicButton, NewProjectFlow, NotificationCenter, NotificationEvent, PENDING_LOOKUP_MS, PENDING_RECOVERY_KEY, PENDING_TASK_MESSAGE, PREMIUM_TIER_TAG, PROJECTS_BASE_TAB_ID, PROMPT_BINDINGS, PersistedGridView, ProgressiveLoadingChip, ProjectDetail, ProjectUsageContent, ProjectsTable, REFERRAL_OFFER, RecoveryKeyDownload, RelatedDocumentsCell, RunStatsBadges, RunningSubagents, SEARCH_FIELD_OPTIONS, SETTINGS_SECTION_IDS, STANDARD_TIER_TAG, SessionStatusIcon, SharedProjects, SourceChips, SsoResendVerificationButton, StatusCell, StorageBreakdown, StorageItemsTable, StorageTiers, StreamedArtifact, TILE_DEFAULT, TILE_MAX, TILE_MIN, ThreadSwitcher, UserAvatar, ViewSelector, WORKSPACES_TAB_ID, WorkflowLaunchHost, WorkflowRunStatusCell, WorkflowRunThread, WorkflowStepMessage, accountSettingsSection, backUpOnSignup, bookingCancelLink, buildNotificationCenterItems, buildProjectSummaries, chatSettingsSection, closeAccessRequestReview, connectedAppsSettingsSection, connectionSettingsSection, countNotificationTypes, createDocumentColumns, createEventCall, createNotificationTargetOpener, createTagColumn, deduplicateByContentHash, defaultHost, describePlan, distinctPeers, documentFamilyMeta, documentFieldContent, filesViewMode, filterNotificationCenterItems, groupFallbackName, identifyOAuthClient, isActiveDocumentStatus, joinEventMeeting, loadEventWebinar, mailSettingsSection, openMeetingLink, organisationSettingsSection, parseArbiCallUrl, parseOAuthConsentRequest, parseQuotaError, parseTypedSkill, primaryProjectWorkspace, privacySettingsSection, renderConnectedUser, renderSessionStatusIcon, requestProjectBillingFocus, resolveAttendeeUsers, resolveAttendeeUsersRemote, resolveCallPeers, resolveCallPeersRemote, resolveLaunchInputs, resolveMailbox, resolveSsoName, reviewAccessRequest, reviewProgress, shareEventCall, startMenuItem, storageSettingsSection, suppliedKinds, threadStateOf, toWorkspaceSummary, transferOutcome, updateEventWebinarRoles, usageSettingsSection, useAccessRequestUnderReview, useAddFromUrls, useAiReviewStore, useAuthPages, useAutoRefreshPendingProjects, useConnectedCalendarCalls, useConnectedNotificationBell, useConnectedShellWorkspaces, useConnectedThreadActivity, useConnectedWorkspaceList, useConnectedWorkspaceSettings, useDocumentBulkActions, useDocumentFilters, useDocumentFolders, useDocumentGridSync, useDocumentNavigation, useDocumentTable, useExportStore, useFilesDialogs, useFilesGridStates, useFilesPrefs, useFilesStore, useLaunchWorkflow, useMemberLookup, useMessengerRows, useModelPicker, useNotificationBellEntry, useOpenBillingPortal, useOpenChunk, useOpenNotificationTarget, useOpenWorkspaceActivityTarget, useOpenWorkspaceIcon, usePendingFolders, usePendingTaskThread, useProjectBillingFocus, useProjectSummaries, useProjectSummary, useReferralReward, useRenderTaskPerson, useResolvedDocStatus, useSkillsEnabled, useSlashItems, useSlashSkillWorkflows, useSsoSignIn, useStartRequestedDraft, useTableViews, useTaskPeople, useTaskStart, useThreadLabels, useThreadTabs, useWorkflowDefinitions, useWorkflowLaunch, useWorkflowTasks, useWorkspaceDocTitles, viewsOfTable, webinarRolesByUser, windowLabel, withMissingTableViews, withTableView, withoutTableView, workflowRunView };
38441
+ export { AddAddonDialog, AddFromAccountsButton, AgentBarShell, AgentControlBar, AgentSteps, AnswerTable, AskAgainContext, BACKFILL_OPTIONS, BULK_REPROCESS_LIMIT, BillingProjectEntity, ChangePlanDialog, ChatAttachmentList, ConnectedAccountAccessBadge, ConnectedAccountSettings, ConnectedAddContacts, ConnectedAgentChat, ConnectedAgentChatPanel, ConnectedAgentConfigForm, ConnectedAgentCreator, ConnectedAiReview, ConnectedAppsSettings, ConnectedAuthorizeAgent, ConnectedBranchControls, ConnectedBulkTagEditor, ConnectedCalendar, ConnectedChatThread, ConnectedCitationRenderer, ConnectedCompactConversation, ConnectedConfigForm, ConnectedContactCardForm, ConnectedContactToggle, ConnectedContactsDirectory, ConnectedConversation, ConnectedConversationDocumentPicker, ConnectedConversationEmpty, ConnectedConversationStart, ConnectedDangerZone, ConnectedDeploymentStorage, ConnectedDeveloperConfig, ConnectedDriveSyncDialog, ConnectedExportDialog, ConnectedExportPanel, ConnectedFactsPage, ConnectedFieldsEditor, ConnectedFieldsManager, ConnectedFilesBulkActions, ConnectedFilesExplorer, ConnectedFilesPage, ConnectedForgotPassword, ConnectedGrantWorkspaceAccessDialog, ConnectedGroupMembers, ConnectedIdentityVerification, ConnectedLoginPage, ConnectedLogoutDialog, ConnectedMailAccounts, ConnectedMailComposer, ConnectedMailInviteCard, ConnectedMailMessage, ConnectedMailSettings, ConnectedMailSetup, ConnectedMailbox, ConnectedMailboxSyncDialog, ConnectedMessage, ConnectedMessageArea, ConnectedMessageList, ConnectedMessenger, ConnectedModelSelector, ConnectedMoveToFolder, ConnectedNewThreadDialog, ConnectedNotificationCenter, ConnectedNotificationPreferences, ConnectedOAuthConsentPage, ConnectedPasswordChangeDialog, ConnectedPremiumModels, ConnectedPrivacySettings, ConnectedProfileCard, ConnectedProjectEntity, ConnectedProjectStorage, ConnectedProjectsPanel, ConnectedPublicBooking, ConnectedQuotaDialog, ConnectedRecentlyDeletedButton, ConnectedRecoveryKeyDialog, ConnectedRequestWorkspaceAccess, ConnectedRequireVerified, ConnectedSearchPage, ConnectedSecuritySection, ConnectedSessionsRow, ConnectedSettingsPage, ConnectedSharePointAdminConsentPage, ConnectedSharedFilesPage, ConnectedSignatureVerifyPage, ConnectedSkillUpload, ConnectedSkillsLibrary, ConnectedSsoCallback, ConnectedStorageProjectCard, ConnectedStorageSettings, ConnectedTagEditorDialog, ConnectedTagEntity, ConnectedTagForm, ConnectedTagTable, ConnectedTagsPage, ConnectedTaskAccessRequest, ConnectedTaskActivityDialog, ConnectedTaskComposer, ConnectedTaskStartDialog, ConnectedThreadFollow, ConnectedThreadLauncher, ConnectedThreadTabs, ConnectedThreadTaskBar, ConnectedThreadsPreview, ConnectedTransferWatcher, ConnectedUpcomingEvents, ConnectedUpload, ConnectedUploadDropzone, ConnectedUserEntity, ConnectedWelcomeDialog, ConnectedWorkflowHistory, ConnectedWorkflowRunner, ConnectedWorkflowStart, ConnectedWorkspaceActivity, ConnectedWorkspaceDashboard, ConnectedWorkspaceEntity, ConnectedWorkspaceList, ConnectedWorkspaceMembers, ConnectedWorkspaceNotificationMenu, ConnectedWorkspaceSettings, ConnectedWorkspaceTrash, ConversationAlert, ConversationComposer2 as ConversationComposer, ConversationEntity, ConversationSendButton, ConversationStatusCell, DEFAULT_CONNECTED_SEARCH_PAGE_LABELS, DEFAULT_CONNECTED_SKILL_UPLOAD_LABELS, DEFAULT_CONNECTED_WORKFLOW_RUNNER_LABELS, DEFAULT_OAUTH_PERMISSIONS, DEFAULT_PROJECTS_LIST_LABELS, DEFAULT_PROJECT_LIST_COLUMNS, DEFAULT_SEARCH_FIELDS, DEFAULT_SEARCH_ROW_LABELS, DEFAULT_SETTINGS_SECTIONS, DEFAULT_TIMELINE_LABEL_WIDTH, DEFAULT_WORKSPACE_LIST_LABELS, DeveloperFooter, DocumentFolderCell, DocumentLabelsCell, DocumentNameCell, DocumentSharedCell, DocumentStatusGlyph, DocumentSyncGlyph, DocumentUser, DocumentsFilterBarActions, DocumentsUploadButton, EmptyWorkspaceUpload, FACTS_GRID_ID, FILES_PREFS_KEY, FileTooltipContent, ImportVcfButton, ImportVcfSummary, InvoicesModal, LOOK_AGAIN_LABEL, MessageDetailsModal, MessageLiveSeconds, MicButton, NewProjectFlow, NotificationCenter, NotificationEvent, PENDING_LOOKUP_MS, PENDING_RECOVERY_KEY, PENDING_TASK_MESSAGE, PREMIUM_TIER_TAG, PROJECTS_BASE_TAB_ID, PROMPT_BINDINGS, PersistedGridView, ProgressiveLoadingChip, ProjectDetail, ProjectUsageContent, ProjectsTable, REFERRAL_OFFER, RecoveryKeyDownload, RelatedDocumentsCell, RunStatsBadges, RunningSubagents, SEARCH_FIELD_OPTIONS, SETTINGS_SECTION_IDS, STANDARD_TIER_TAG, SessionStatusIcon, SharedProjects, SourceChips, SsoResendVerificationButton, StatusCell, StorageBreakdown, StorageItemsTable, StorageTiers, StreamedArtifact, TILE_DEFAULT, TILE_MAX, TILE_MIN, ThreadSwitcher, UserAvatar, ViewSelector, WORKSPACES_TAB_ID, WorkflowLaunchHost, WorkflowRunStatusCell, WorkflowRunThread, WorkflowStepMessage, accountSettingsSection, appearanceSettingsSection, backUpOnSignup, bookingCancelLink, buildNotificationCenterItems, buildProjectSummaries, chatSettingsSection, closeAccessRequestReview, connectedAppsSettingsSection, connectionSettingsSection, countNotificationTypes, createDocumentColumns, createEventCall, createNotificationTargetOpener, createTagColumn, deduplicateByContentHash, defaultHost, describePlan, distinctPeers, documentFamilyMeta, documentFieldContent, filesViewMode, filterNotificationCenterItems, formatStorageGb, groupFallbackName, identifyOAuthClient, isActiveDocumentStatus, joinEventMeeting, loadEventWebinar, mailSettingsSection, openMeetingLink, openSsoPopup, organisationSettingsSection, parseArbiCallUrl, parseOAuthConsentRequest, parseQuotaError, parseTypedSkill, primaryProjectWorkspace, privacySettingsSection, renderConnectedUser, renderSessionStatusIcon, requestProjectBillingFocus, resolveAttendeeUsers, resolveAttendeeUsersRemote, resolveCallPeers, resolveCallPeersRemote, resolveLaunchInputs, resolveMailbox, resolveSsoName, reviewAccessRequest, reviewProgress, shareEventCall, startMenuItem, storageSettingsSection, suppliedKinds, threadStateOf, toWorkspaceSummary, transferOutcome, updateEventWebinarRoles, usageSettingsSection, useAccessRequestUnderReview, useAddFromUrls, useAiReviewStore, useAuthPages, useAutoRefreshPendingProjects, useConnectedCalendarCalls, useConnectedNotificationBell, useConnectedShellWorkspaces, useConnectedThreadActivity, useConnectedWorkspaceList, useConnectedWorkspaceSettings, useDocumentBulkActions, useDocumentFilters, useDocumentFolders, useDocumentGridSync, useDocumentNavigation, useDocumentTable, useExportStore, useFilesDialogs, useFilesGridStates, useFilesPrefs, useFilesStore, useLaunchWorkflow, useMemberLookup, useMessengerRows, useModelPicker, useNotificationBellEntry, useOpenBillingPortal, useOpenChunk, useOpenNotificationTarget, useOpenWorkspaceActivityTarget, useOpenWorkspaceIcon, usePendingFolders, usePendingTaskThread, useProjectBillingFocus, useProjectSummaries, useProjectSummary, useReferralReward, useRenderTaskPerson, useResolvedDocStatus, useSkillsEnabled, useSlashItems, useSlashSkillWorkflows, useSsoSignIn, useStartRequestedDraft, useTableViews, useTaskPeople, useTaskStart, useThreadLabels, useThreadTabs, useWorkflowDefinitions, useWorkflowLaunch, useWorkflowTasks, useWorkspaceDocTitles, viewsOfTable, webinarRolesByUser, windowLabel, withMissingTableViews, withTableView, withoutTableView, workflowRunView };
37945
38442
  //# sourceMappingURL=index.js.map
37946
38443
  //# sourceMappingURL=index.js.map