@kortix/ui 0.14.8 → 0.14.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (567) hide show
  1. package/README.md +2 -2
  2. package/dist/_vendor/kortix-shared.js +116 -3
  3. package/dist/_vendor/shared/app-config.d.ts +175 -0
  4. package/dist/_vendor/shared/artifact-comments.d.ts +235 -0
  5. package/dist/_vendor/shared/channel-descriptors.d.ts +96 -0
  6. package/dist/_vendor/shared/channel-message.d.ts +45 -5
  7. package/dist/_vendor/shared/index.d.ts +2 -0
  8. package/dist/_vendor/shared/space-slug.d.ts +37 -0
  9. package/dist/access/access/access-detail-shell.js +1 -1
  10. package/dist/access/access/principal-picker.d.ts +11 -0
  11. package/dist/access/access/principal-picker.js +3 -2
  12. package/dist/apps/app-preview-pool.d.ts +7 -2
  13. package/dist/apps/app-preview-pool.js +30 -7
  14. package/dist/apps/app-shared.d.ts +22 -15
  15. package/dist/apps/app-shared.js +37 -19
  16. package/dist/apps/index.d.ts +2 -2
  17. package/dist/apps/index.js +2 -2
  18. package/dist/artifacts/artifact-frame.d.ts +16 -0
  19. package/dist/artifacts/artifact-frame.js +55 -0
  20. package/dist/artifacts/artifact-session.d.ts +18 -0
  21. package/dist/artifacts/artifact-session.js +101 -0
  22. package/dist/artifacts/frame-policy.d.ts +30 -0
  23. package/dist/artifacts/frame-policy.js +61 -0
  24. package/dist/artifacts/index.d.ts +3 -0
  25. package/dist/artifacts/index.js +5 -0
  26. package/dist/browser/sandbox-browser-chrome.d.ts +4 -1
  27. package/dist/browser/sandbox-browser-chrome.js +2 -2
  28. package/dist/customize/agents/agent-grant-pages.d.ts +5 -1
  29. package/dist/customize/agents/agent-grant-pages.js +30 -4
  30. package/dist/customize/agents/agent-page.js +3 -1
  31. package/dist/customize/agents/agent-policy-sets.d.ts +43 -0
  32. package/dist/customize/agents/agent-policy-sets.js +72 -0
  33. package/dist/customize/agents/agent-triggers-section.js +2 -1
  34. package/dist/customize/connectors/add-mcp/add-mcp-server-dialog.d.ts +6 -1
  35. package/dist/customize/connectors/add-mcp/add-mcp-server-dialog.js +10 -4
  36. package/dist/customize/connectors/agent-access.d.ts +35 -0
  37. package/dist/customize/connectors/agent-access.js +77 -0
  38. package/dist/customize/connectors/catalog/browse-sections.d.ts +2 -29
  39. package/dist/customize/connectors/catalog/browse-sections.js +7 -74
  40. package/dist/customize/connectors/catalog/catalog-entry.d.ts +18 -37
  41. package/dist/customize/connectors/catalog/catalog-entry.js +28 -40
  42. package/dist/customize/connectors/catalog/connector-browse.d.ts +3 -32
  43. package/dist/customize/connectors/catalog/connector-browse.js +19 -50
  44. package/dist/customize/connectors/catalog/use-catalog.d.ts +20 -59
  45. package/dist/customize/connectors/catalog/use-catalog.js +48 -175
  46. package/dist/customize/connectors/connector-identity.d.ts +9 -11
  47. package/dist/customize/connectors/connector-identity.js +13 -42
  48. package/dist/customize/connectors/connector-moves-banner.d.ts +2 -1
  49. package/dist/customize/connectors/connector-moves-banner.js +4 -6
  50. package/dist/customize/connectors/connector-routes.d.ts +21 -9
  51. package/dist/customize/connectors/connector-routes.js +29 -20
  52. package/dist/customize/connectors/connectors-page.js +53 -82
  53. package/dist/customize/connectors/detail/app-page.js +226 -98
  54. package/dist/customize/connectors/detail/computer-app-page.d.ts +16 -0
  55. package/dist/customize/connectors/detail/computer-app-page.js +39 -0
  56. package/dist/customize/connectors/detail/connector-accounts.js +3 -1
  57. package/dist/customize/connectors/detail/connector-advanced-tools.d.ts +4 -1
  58. package/dist/customize/connectors/detail/connector-advanced-tools.js +2 -2
  59. package/dist/customize/connectors/detail/connector-agents.d.ts +14 -0
  60. package/dist/customize/connectors/detail/connector-agents.js +69 -0
  61. package/dist/customize/connectors/detail/connector-detail-tabs.js +2 -1
  62. package/dist/customize/connectors/detail/connector-move-row.d.ts +8 -5
  63. package/dist/customize/connectors/detail/connector-move-row.js +23 -14
  64. package/dist/customize/connectors/detail/connector-page.d.ts +4 -1
  65. package/dist/customize/connectors/detail/connector-page.js +14 -10
  66. package/dist/customize/connectors/detail/connector-policy-sets.d.ts +28 -0
  67. package/dist/customize/connectors/detail/connector-policy-sets.js +203 -0
  68. package/dist/customize/connectors/detail/connector-settings.d.ts +4 -1
  69. package/dist/customize/connectors/detail/connector-settings.js +7 -3
  70. package/dist/customize/connectors/detail/connector-status.d.ts +19 -6
  71. package/dist/customize/connectors/detail/connector-status.js +34 -10
  72. package/dist/customize/connectors/detail/connector-tabs.d.ts +4 -1
  73. package/dist/customize/connectors/detail/connector-tabs.js +8 -2
  74. package/dist/customize/connectors/detail/connector-tools.d.ts +3 -3
  75. package/dist/customize/connectors/detail/connector-tools.js +105 -48
  76. package/dist/customize/connectors/detail/email-inboxes.d.ts +43 -0
  77. package/dist/customize/connectors/detail/email-inboxes.js +184 -0
  78. package/dist/customize/connectors/detail/provider-info.d.ts +1 -1
  79. package/dist/customize/connectors/detail/provider-info.js +2 -2
  80. package/dist/customize/connectors/detail/status-badge.d.ts +1 -1
  81. package/dist/customize/connectors/detail/status-badge.js +4 -5
  82. package/dist/customize/connectors/detail/use-connector-detail.d.ts +6 -0
  83. package/dist/customize/connectors/detail/use-connector-detail.js +14 -4
  84. package/dist/customize/connectors/install/install-dialog.d.ts +23 -0
  85. package/dist/customize/connectors/install/install-dialog.js +40 -0
  86. package/dist/customize/connectors/install/install.d.ts +13 -2
  87. package/dist/customize/connectors/install/install.js +9 -4
  88. package/dist/customize/connectors/install/use-install.d.ts +19 -2
  89. package/dist/customize/connectors/install/use-install.js +65 -37
  90. package/dist/customize/connectors/install/way-kind.d.ts +5 -0
  91. package/dist/customize/connectors/install/way-kind.js +16 -0
  92. package/dist/customize/connectors/provider-label.d.ts +2 -1
  93. package/dist/customize/connectors/provider-label.js +13 -3
  94. package/dist/customize/connectors/tools/pattern-rule-draft.d.ts +4 -0
  95. package/dist/customize/connectors/tools/pattern-rule-draft.js +12 -3
  96. package/dist/customize/connectors/tools/policy-sets.d.ts +27 -0
  97. package/dist/customize/connectors/tools/policy-sets.js +41 -0
  98. package/dist/customize/connectors/tools/tool-groups.d.ts +32 -9
  99. package/dist/customize/connectors/tools/tool-groups.js +78 -16
  100. package/dist/customize/connectors/tools/tool-policy-control.d.ts +11 -10
  101. package/dist/customize/connectors/tools/tool-policy-control.js +15 -16
  102. package/dist/customize/connectors/tools/tool-policy-labels.d.ts +6 -5
  103. package/dist/customize/connectors/tools/tool-policy-labels.js +17 -16
  104. package/dist/customize/connectors/tools/tool-policy.d.ts +50 -4
  105. package/dist/customize/connectors/tools/tool-policy.js +74 -8
  106. package/dist/customize/connectors/use-agent-access.d.ts +85 -0
  107. package/dist/customize/connectors/use-agent-access.js +72 -0
  108. package/dist/customize/migrate-to-v2/index.d.ts +1 -2
  109. package/dist/customize/migrate-to-v2/index.js +1 -2
  110. package/dist/customize/migrate-to-v2/migration-prompt.d.ts +12 -25
  111. package/dist/customize/migrate-to-v2/migration-prompt.js +34 -236
  112. package/dist/customize/migrate-to-v2/upgrade-defs.d.ts +1 -1
  113. package/dist/customize/migrate-to-v2/upgrade-defs.js +7 -6
  114. package/dist/customize/migrate-to-v2/upgrade-view.js +7 -7
  115. package/dist/customize/migrate-to-v2/use-run-upgrade.d.ts +3 -3
  116. package/dist/customize/providers/provider-accordion.js +17 -2
  117. package/dist/customize/sections/component/channel-access-panel.d.ts +16 -0
  118. package/dist/customize/sections/component/channel-access-panel.js +146 -0
  119. package/dist/customize/sections/component/channel-connect-hero.d.ts +3 -2
  120. package/dist/customize/sections/component/channel-connect-hero.js +3 -2
  121. package/dist/customize/sections/component/channel-hero-frame.d.ts +31 -0
  122. package/dist/customize/sections/component/channel-hero-frame.js +40 -0
  123. package/dist/customize/sections/component/channel-mocks.d.ts +6 -0
  124. package/dist/customize/sections/component/channel-mocks.js +46 -0
  125. package/dist/customize/sections/component/channel-row.d.ts +13 -3
  126. package/dist/customize/sections/component/channel-row.js +10 -4
  127. package/dist/customize/sections/component/email-connect-form.d.ts +27 -0
  128. package/dist/customize/sections/component/email-connect-form.js +183 -0
  129. package/dist/customize/sections/component/slack-connect-card.d.ts +7 -0
  130. package/dist/customize/sections/component/slack-connect-card.js +2 -3
  131. package/dist/customize/sections/component/teams-connect-card.d.ts +7 -0
  132. package/dist/customize/sections/component/teams-connect-card.js +2 -3
  133. package/dist/customize/sections/component/telegram-channel-row.js +21 -28
  134. package/dist/customize/sections/connectors-view.d.ts +1 -15
  135. package/dist/customize/sections/connectors-view.js +81 -314
  136. package/dist/customize/sections/view/agent-editor-catalog.js +10 -0
  137. package/dist/customize/sections/view/channels-view.d.ts +6 -1
  138. package/dist/customize/sections/view/channels-view.js +72 -81
  139. package/dist/customize/sections/view/gateway/gateway-overview.js +10 -2
  140. package/dist/customize/settings/rail.js +9 -0
  141. package/dist/customize/settings/settings-tabs.d.ts +1 -1
  142. package/dist/customize/settings/settings-tabs.js +1 -0
  143. package/dist/customize/settings/tabs/chrome-connections-tab.d.ts +6 -0
  144. package/dist/customize/settings/tabs/chrome-connections-tab.js +99 -0
  145. package/dist/customize/settings/tabs/experimental-tab.js +35 -16
  146. package/dist/customize/shared/catalog/catalog-empty-state.d.ts +4 -15
  147. package/dist/customize/shared/catalog/catalog-empty-state.js +9 -7
  148. package/dist/customize/shared/channels-switch-dialog.d.ts +18 -0
  149. package/dist/customize/shared/channels-switch-dialog.js +30 -0
  150. package/dist/customize/shared/feature-gate-screen.js +27 -9
  151. package/dist/customize/shared/use-customize-prefetch.d.ts +2 -3
  152. package/dist/customize/shared/use-customize-prefetch.js +9 -27
  153. package/dist/customize/triggers/schedule/post-to-field.d.ts +18 -0
  154. package/dist/customize/triggers/schedule/post-to-field.js +49 -0
  155. package/dist/customize/triggers/schedule/schedule-copy.d.ts +10 -6
  156. package/dist/customize/triggers/schedule/schedule-copy.js +42 -11
  157. package/dist/customize/triggers/schedule/schedule-detail-sheet.js +2 -1
  158. package/dist/customize/triggers/schedule/trigger-composer-logic.d.ts +22 -0
  159. package/dist/customize/triggers/schedule/trigger-composer-logic.js +25 -0
  160. package/dist/customize/triggers/schedule/trigger-composer.d.ts +5 -0
  161. package/dist/customize/triggers/schedule/trigger-composer.js +23 -14
  162. package/dist/customize/triggers/schedule/trigger-edit-logic.js +3 -0
  163. package/dist/customize/triggers/schedule/trigger-filter.js +1 -1
  164. package/dist/customize/triggers/schedule/trigger-runs-logic.d.ts +2 -2
  165. package/dist/customize/triggers/schedule/trigger-runs-panel.js +1 -0
  166. package/dist/customize/triggers/schedule/trigger-toast.js +2 -1
  167. package/dist/customize/triggers/schedule-view.js +5 -2
  168. package/dist/files/index.d.ts +1 -0
  169. package/dist/files/index.js +1 -0
  170. package/dist/files/project/change-request-recovery.d.ts +1 -26
  171. package/dist/files/project/change-request-recovery.js +1 -59
  172. package/dist/files/project/components/change-request-detail-dialog.js +13 -3
  173. package/dist/files/project/components/drive-explorer.js +15 -15
  174. package/dist/files/project/components/drive-toolbar.d.ts +16 -2
  175. package/dist/files/project/components/drive-toolbar.js +14 -5
  176. package/dist/files/project/hooks/use-change-request-recovery.js +3 -19
  177. package/dist/files/project/hooks/use-change-requests.d.ts +1 -0
  178. package/dist/files/project/hooks/use-change-requests.js +11 -2
  179. package/dist/files/renderers/image-frame.d.ts +48 -0
  180. package/dist/files/renderers/image-frame.js +59 -0
  181. package/dist/files/renderers/image-renderer.d.ts +11 -1
  182. package/dist/files/renderers/image-renderer.js +13 -3
  183. package/dist/files/renderers/pdf/pdf-clipboard.d.ts +2 -0
  184. package/dist/files/renderers/pdf/pdf-clipboard.js +21 -0
  185. package/dist/files/renderers/pdf/pdf-viewer.js +4 -2
  186. package/dist/files/renderers/show-content-renderer.d.ts +9 -1
  187. package/dist/files/renderers/show-content-renderer.js +56 -14
  188. package/dist/files/runtime/file-source.js +2 -0
  189. package/dist/files/runtime/hooks/use-binary-blob.d.ts +10 -1
  190. package/dist/files/runtime/hooks/use-binary-blob.js +10 -4
  191. package/dist/files/runtime/hooks/use-shared-image.d.ts +41 -0
  192. package/dist/files/runtime/hooks/use-shared-image.js +177 -0
  193. package/dist/files/viewer/file-content-renderer.d.ts +22 -1
  194. package/dist/files/viewer/file-content-renderer.js +50 -7
  195. package/dist/files/viewer/file-header.d.ts +7 -3
  196. package/dist/files/viewer/file-header.js +20 -11
  197. package/dist/files/viewer/file-preview-modal.d.ts +1 -1
  198. package/dist/files/viewer/file-preview-modal.js +10 -22
  199. package/dist/files/viewer/file-source.d.ts +13 -0
  200. package/dist/files/viewer/use-file-content-state.d.ts +2 -0
  201. package/dist/files/viewer/use-file-content-state.js +28 -10
  202. package/dist/files/viewer/viewer-actions.d.ts +3 -1
  203. package/dist/files/viewer/viewer-actions.js +2 -2
  204. package/dist/hooks/use-media-query.d.ts +1 -0
  205. package/dist/hooks/use-mobile.d.ts +5 -0
  206. package/dist/hooks/use-mobile.js +8 -0
  207. package/dist/i18n/en.d.ts +1062 -85
  208. package/dist/i18n/en.js +1078 -101
  209. package/dist/i18n/ui-catalog/localize-ui-catalog.js +4 -0
  210. package/dist/i18n/ui-catalog/remaining-ui-translation-keys.generated.js +15 -3
  211. package/dist/index.d.ts +2 -2
  212. package/dist/index.js +2 -2
  213. package/dist/internal/account-hub/account-settings-sidebar.js +1 -1
  214. package/dist/internal/account-hub/hub-sheet.d.ts +9 -1
  215. package/dist/internal/account-hub/hub-sheet.js +21 -5
  216. package/dist/internal/account-hub/sections.d.ts +1 -1
  217. package/dist/internal/account-hub/sections.js +2 -1
  218. package/dist/internal/apps-and-extensions/apps-modal.d.ts +9 -0
  219. package/dist/internal/apps-and-extensions/apps-modal.js +107 -0
  220. package/dist/internal/auth/auth-card-shell.js +3 -3
  221. package/dist/internal/chrome/browser-icon.d.ts +24 -0
  222. package/dist/internal/chrome/browser-icon.js +58 -0
  223. package/dist/internal/chrome/chrome-card-state.d.ts +16 -0
  224. package/dist/internal/chrome/chrome-card-state.js +9 -0
  225. package/dist/internal/chrome/chrome-connect.d.ts +69 -0
  226. package/dist/internal/chrome/chrome-connect.js +178 -0
  227. package/dist/internal/chrome/chrome-mock.d.ts +4 -0
  228. package/dist/internal/chrome/chrome-mock.js +15 -0
  229. package/dist/internal/chrome/chrome-names.d.ts +15 -0
  230. package/dist/internal/chrome/chrome-names.js +35 -0
  231. package/dist/internal/chrome/extension.d.ts +47 -0
  232. package/dist/internal/chrome/extension.js +91 -0
  233. package/dist/internal/chrome/use-chrome-offered.d.ts +11 -0
  234. package/dist/internal/chrome/use-chrome-offered.js +22 -0
  235. package/dist/internal/components/agent-mark.js +5 -2
  236. package/dist/internal/connector-logo/connector-logo-source.d.ts +64 -0
  237. package/dist/internal/connector-logo/connector-logo-source.js +49 -0
  238. package/dist/internal/connector-logo/connector-logo.d.ts +39 -0
  239. package/dist/internal/connector-logo/connector-logo.js +56 -0
  240. package/dist/internal/connector-logo/connector-mark-files.d.ts +11 -0
  241. package/dist/internal/connector-logo/connector-mark-files.js +35 -0
  242. package/dist/internal/files/file-read-retry.d.ts +13 -0
  243. package/dist/internal/files/file-read-retry.js +23 -3
  244. package/dist/internal/files/session-drive-files.d.ts +5 -1
  245. package/dist/internal/files/session-drive-files.js +7 -2
  246. package/dist/internal/hooks/channels/use-channels-installations.d.ts +32 -5
  247. package/dist/internal/hooks/channels/use-channels-installations.js +55 -7
  248. package/dist/internal/hooks/channels/use-email-inboxes.d.ts +19 -0
  249. package/dist/internal/hooks/channels/use-email-inboxes.js +48 -0
  250. package/dist/internal/hooks/connectors/use-add-account.js +1 -1
  251. package/dist/internal/hooks/index.d.ts +1 -1
  252. package/dist/internal/hooks/index.js +1 -1
  253. package/dist/internal/hooks/projects/use-new-project-session.d.ts +9 -0
  254. package/dist/internal/hooks/projects/use-new-project-session.js +28 -12
  255. package/dist/internal/hooks/use-auto-scroll.d.ts +8 -1
  256. package/dist/internal/hooks/use-auto-scroll.js +4 -4
  257. package/dist/internal/icons/edge.d.ts +5 -0
  258. package/dist/internal/icons/edge.js +10 -0
  259. package/dist/internal/icons/telegram.d.ts +5 -0
  260. package/dist/internal/icons/telegram.js +6 -1
  261. package/dist/internal/layout/nav-hover-card.d.ts +35 -0
  262. package/dist/internal/layout/nav-hover-card.js +84 -0
  263. package/dist/internal/layout/project-nav-row.d.ts +3 -1
  264. package/dist/internal/layout/project-nav-row.js +3 -2
  265. package/dist/internal/layout/project-page-header.d.ts +4 -2
  266. package/dist/internal/layout/project-page-header.js +4 -3
  267. package/dist/internal/layout/project-settings-nav.js +59 -2
  268. package/dist/internal/lib/browser-error-noise.d.ts +1 -1
  269. package/dist/internal/lib/browser-error-noise.js +1 -1
  270. package/dist/internal/lib/browser-noise/rules/extensions.js +17 -3
  271. package/dist/internal/lib/browser-noise/rules/injected-scripts.d.ts +7 -0
  272. package/dist/internal/lib/browser-noise/rules/injected-scripts.js +15 -0
  273. package/dist/internal/lib/detect-os.d.ts +43 -0
  274. package/dist/internal/lib/detect-os.js +70 -0
  275. package/dist/internal/lib/manifest-version.d.ts +1 -1
  276. package/dist/internal/lib/manifest-version.js +2 -2
  277. package/dist/internal/lib/memory-href.d.ts +16 -0
  278. package/dist/internal/lib/memory-href.js +46 -0
  279. package/dist/internal/lib/use-project-feature-flags.js +13 -9
  280. package/dist/internal/lib/utils/heic-convert.d.ts +1 -1
  281. package/dist/internal/lib/utils/heic-convert.js +3 -4
  282. package/dist/internal/lib/web-notifications.d.ts +20 -0
  283. package/dist/internal/lib/web-notifications.js +48 -4
  284. package/dist/internal/notifications/notification-bell.d.ts +4 -1
  285. package/dist/internal/notifications/notification-bell.js +2 -2
  286. package/dist/internal/selection/selection-bar.d.ts +2 -1
  287. package/dist/internal/selection/selection-bar.js +1 -1
  288. package/dist/internal/stores/apps-modal-store.d.ts +8 -0
  289. package/dist/internal/stores/apps-modal-store.js +6 -0
  290. package/dist/internal/stores/composer-prefill-store.d.ts +12 -5
  291. package/dist/internal/stores/file-preview-store.d.ts +29 -2
  292. package/dist/internal/stores/file-preview-store.js +19 -1
  293. package/dist/internal/stores/kortix-computer-store.js +3 -0
  294. package/dist/internal/stores/sidebar-nav-store.d.ts +1 -1
  295. package/dist/internal/stores/sidebar-nav-store.js +3 -1
  296. package/dist/lib/routes.d.ts +13 -1
  297. package/dist/lib/routes.js +13 -0
  298. package/dist/markdown/index.d.ts +2 -1
  299. package/dist/markdown/index.js +2 -1
  300. package/dist/markdown/setup-links/approval-decision.d.ts +1 -0
  301. package/dist/markdown/setup-links/approval-decision.js +9 -3
  302. package/dist/markdown/setup-links/connector-handshake.d.ts +3 -1
  303. package/dist/markdown/setup-links/connector-handshake.js +12 -10
  304. package/dist/markdown/setup-links/secret-intake-form.d.ts +0 -10
  305. package/dist/markdown/setup-links/secret-intake-form.js +1 -1
  306. package/dist/markdown/setup-links/show-connect-hero.d.ts +28 -0
  307. package/dist/markdown/setup-links/show-connect-hero.js +91 -0
  308. package/dist/markdown/unified-markdown.js +5 -5
  309. package/dist/primitives/badge.d.ts +1 -1
  310. package/dist/primitives/badge.js +2 -0
  311. package/dist/primitives/disclosure.js +14 -2
  312. package/dist/primitives/empty-art.d.ts +12 -0
  313. package/dist/primitives/empty-art.js +11 -0
  314. package/dist/primitives/empty-state.d.ts +2 -2
  315. package/dist/primitives/empty-state.js +6 -5
  316. package/dist/primitives/mermaid-renderer.d.ts +2 -0
  317. package/dist/primitives/mermaid-renderer.js +21 -15
  318. package/dist/primitives/resizable.js +6 -1
  319. package/dist/primitives/resize-seam.d.ts +11 -0
  320. package/dist/primitives/resize-seam.js +12 -0
  321. package/dist/primitives/sidebar-panel.js +4 -7
  322. package/dist/primitives/tabs.d.ts +14 -1
  323. package/dist/primitives/tabs.js +1 -1
  324. package/dist/providers/ui-provider.d.ts +9 -0
  325. package/dist/session/composer/ComposerAboveCard.d.ts +1 -1
  326. package/dist/session/composer/ComposerAboveCard.js +2 -2
  327. package/dist/session/composer/ComposerCard.d.ts +1 -1
  328. package/dist/session/composer/ComposerCard.js +3 -3
  329. package/dist/session/composer/agent-selector.d.ts +13 -1
  330. package/dist/session/composer/agent-selector.js +25 -5
  331. package/dist/session/composer/composer-agent-access.d.ts +15 -0
  332. package/dist/session/composer/composer-agent-access.js +27 -0
  333. package/dist/session/composer/composer-chat-input.d.ts +8 -2
  334. package/dist/session/composer/composer-chat-input.js +8 -6
  335. package/dist/session/composer/composer-logic.d.ts +16 -0
  336. package/dist/session/composer/composer-logic.js +12 -0
  337. package/dist/session/composer/composer-underbar.d.ts +3 -1
  338. package/dist/session/composer/composer-underbar.js +4 -3
  339. package/dist/session/composer/composer.d.ts +15 -1
  340. package/dist/session/composer/composer.js +19 -1
  341. package/dist/session/composer/draft/composer-draft.d.ts +6 -2
  342. package/dist/session/composer/draft/composer-draft.js +5 -1
  343. package/dist/session/composer/reasoning-effort-selector.js +1 -1
  344. package/dist/session/models/chatgpt-connection-button.d.ts +11 -0
  345. package/dist/session/models/chatgpt-connection-button.js +54 -0
  346. package/dist/session/models/model-selector.js +5 -2
  347. package/dist/session/models/use-model-connection-gate.d.ts +5 -5
  348. package/dist/session/models/use-model-connection-gate.js +5 -5
  349. package/dist/session/outcomes/jump-to-outcome.d.ts +10 -0
  350. package/dist/session/outcomes/jump-to-outcome.js +11 -0
  351. package/dist/session/outcomes/session-outcomes-bridge.d.ts +14 -0
  352. package/dist/session/outcomes/session-outcomes-bridge.js +12 -0
  353. package/dist/session/outcomes/session-outcomes-provider.d.ts +3 -1
  354. package/dist/session/outcomes/session-outcomes-provider.js +33 -3
  355. package/dist/session/panel/easy/app-preview.d.ts +10 -0
  356. package/dist/session/panel/easy/app-preview.js +31 -12
  357. package/dist/session/panel/easy/change-requests-card.d.ts +7 -0
  358. package/dist/session/panel/easy/change-requests-card.js +17 -0
  359. package/dist/session/panel/easy/easy-panel-logic.js +7 -1
  360. package/dist/session/panel/easy/easy-panel.js +5 -2
  361. package/dist/session/panel/easy/file-preview.js +1 -1
  362. package/dist/session/panel/easy/outputs-card.d.ts +2 -1
  363. package/dist/session/panel/easy/outputs-card.js +3 -2
  364. package/dist/session/panel/mobile-tool-drawer.js +7 -1
  365. package/dist/session/panel/session-audit-panel.js +9 -2
  366. package/dist/session/panel/session-audit-shared.js +3 -1
  367. package/dist/session/panel/session-detail-panel.js +9 -3
  368. package/dist/session/panel/session-files-explorer.d.ts +9 -0
  369. package/dist/session/panel/session-files-explorer.js +12 -3
  370. package/dist/session/panel/session-panel-provider.d.ts +15 -1
  371. package/dist/session/panel/session-panel-provider.js +32 -7
  372. package/dist/session/panel/shared/derive-panels.d.ts +8 -1
  373. package/dist/session/panel/shared/derive-panels.js +12 -2
  374. package/dist/session/panel/shared/output-priority.js +2 -0
  375. package/dist/session/participants/session-participants.d.ts +8 -2
  376. package/dist/session/participants/session-participants.js +11 -4
  377. package/dist/session/prompts/approval-request.d.ts +5 -0
  378. package/dist/session/prompts/approval-request.js +9 -1
  379. package/dist/session/prompts/session-approval-review.d.ts +9 -0
  380. package/dist/session/prompts/session-approval-review.js +18 -0
  381. package/dist/session/status/session-error-banner.js +2 -49
  382. package/dist/session/status/session-starting-loader.d.ts +14 -2
  383. package/dist/session/status/session-starting-loader.js +16 -4
  384. package/dist/session/thread/after-first-prompt.d.ts +7 -0
  385. package/dist/session/thread/after-first-prompt.js +8 -0
  386. package/dist/session/thread/detect-command.d.ts +12 -0
  387. package/dist/session/thread/detect-command.js +20 -0
  388. package/dist/session/thread/session-chat.d.ts +3 -1
  389. package/dist/session/thread/session-chat.js +377 -252
  390. package/dist/session/thread/session-thread.d.ts +15 -1
  391. package/dist/session/thread/session-thread.js +20 -3
  392. package/dist/session/thread/session-transcript-class.d.ts +5 -1
  393. package/dist/session/thread/session-transcript-class.js +5 -1
  394. package/dist/session/thread/thread-boot-rows.d.ts +36 -0
  395. package/dist/session/thread/thread-boot-rows.js +89 -0
  396. package/dist/session/thread/transcript-rows.d.ts +31 -0
  397. package/dist/session/thread/transcript-rows.js +3 -0
  398. package/dist/session/thread/transcript.d.ts +0 -9
  399. package/dist/session/thread/transcript.js +104 -19
  400. package/dist/session/tool/shared/infrastructure-contexts.d.ts +28 -0
  401. package/dist/session/tool/shared/infrastructure-contexts.js +31 -3
  402. package/dist/session/tool/tool-part-renderer.d.ts +5 -4
  403. package/dist/session/tool/tool-part-renderer.js +8 -3
  404. package/dist/session/tool/tools/bash-tool.js +7 -6
  405. package/dist/session/tool/tools/channel-send-card.d.ts +1 -2
  406. package/dist/session/tool/tools/channel-send.d.ts +2 -1
  407. package/dist/session/tool/tools/codemode-tool.js +1 -1
  408. package/dist/session/tool/tools/connector-tools.js +1 -1
  409. package/dist/session/tool/tools/image-gen-tool.d.ts +1 -1
  410. package/dist/session/tool/tools/image-gen-tool.js +241 -53
  411. package/dist/session/tool/tools/show-tool.js +19 -8
  412. package/dist/session/turn/channel-brand.d.ts +8 -3
  413. package/dist/session/turn/channel-brand.js +20 -4
  414. package/dist/session/turn/message-author.d.ts +8 -0
  415. package/dist/session/turn/message-author.js +24 -0
  416. package/dist/session/turn/message-row.d.ts +52 -0
  417. package/dist/session/turn/message-row.js +44 -0
  418. package/dist/session/turn/plan-anchor.d.ts +1 -1
  419. package/dist/session/turn/plan-anchor.js +1 -1
  420. package/dist/session/turn/user-message.d.ts +14 -6
  421. package/dist/session/turn/user-message.js +35 -15
  422. package/dist/styles.css +1 -1
  423. package/dist/workspace/home/access-requests-bell.d.ts +9 -2
  424. package/dist/workspace/home/access-requests-bell.js +20 -6
  425. package/dist/workspace/home/first-chat.d.ts +8 -21
  426. package/dist/workspace/home/first-chat.js +22 -72
  427. package/dist/workspace/index.d.ts +6 -0
  428. package/dist/workspace/index.js +6 -0
  429. package/dist/workspace/layout/project-home.d.ts +14 -2
  430. package/dist/workspace/layout/project-home.js +60 -21
  431. package/dist/workspace/layout/use-project-home-send.d.ts +9 -1
  432. package/dist/workspace/layout/use-project-home-send.js +82 -3
  433. package/dist/workspace/memory/body-doc.d.ts +17 -0
  434. package/dist/workspace/memory/body-doc.js +208 -0
  435. package/dist/workspace/memory/body-extensions.d.ts +38 -0
  436. package/dist/workspace/memory/body-extensions.js +103 -0
  437. package/dist/workspace/memory/company-memory-page.d.ts +8 -0
  438. package/dist/workspace/memory/company-memory-page.js +16 -0
  439. package/dist/workspace/memory/memory-all.d.ts +20 -0
  440. package/dist/workspace/memory/memory-all.js +27 -0
  441. package/dist/workspace/memory/memory-body.d.ts +19 -0
  442. package/dist/workspace/memory/memory-body.js +139 -0
  443. package/dist/workspace/memory/memory-empty.d.ts +13 -0
  444. package/dist/workspace/memory/memory-empty.js +28 -0
  445. package/dist/workspace/memory/memory-history.d.ts +27 -0
  446. package/dist/workspace/memory/memory-history.js +108 -0
  447. package/dist/workspace/memory/memory-labels.d.ts +16 -0
  448. package/dist/workspace/memory/memory-labels.js +47 -0
  449. package/dist/workspace/memory/memory-page-list.d.ts +34 -0
  450. package/dist/workspace/memory/memory-page-list.js +156 -0
  451. package/dist/workspace/memory/memory-reader.d.ts +58 -0
  452. package/dist/workspace/memory/memory-reader.js +123 -0
  453. package/dist/workspace/memory/memory-view.d.ts +21 -0
  454. package/dist/workspace/memory/memory-view.js +124 -0
  455. package/dist/workspace/memory/remember-popover.d.ts +19 -0
  456. package/dist/workspace/memory/remember-popover.js +61 -0
  457. package/dist/workspace/memory/remember-this.d.ts +12 -0
  458. package/dist/workspace/memory/remember-this.js +89 -0
  459. package/dist/workspace/memory/source-mark.d.ts +18 -0
  460. package/dist/workspace/memory/source-mark.js +79 -0
  461. package/dist/workspace/memory/used-memory-chip.d.ts +14 -0
  462. package/dist/workspace/memory/used-memory-chip.js +61 -0
  463. package/dist/workspace/new/advanced-fields.d.ts +2 -1
  464. package/dist/workspace/new/advanced-fields.js +2 -2
  465. package/dist/workspace/new/source-param.d.ts +1 -1
  466. package/dist/workspace/new/source-param.js +3 -1
  467. package/dist/workspace/new/use-create-workspace.d.ts +8 -10
  468. package/dist/workspace/new/use-create-workspace.js +3 -3
  469. package/dist/workspace/projects/onboarding/app-logo.d.ts +7 -2
  470. package/dist/workspace/projects/onboarding/app-logo.js +6 -13
  471. package/dist/workspace/projects/policies-panel.js +5 -3
  472. package/dist/workspace/review/review-actions.d.ts +4 -2
  473. package/dist/workspace/review/review-actions.js +8 -2
  474. package/dist/workspace/review/review-center.js +11 -7
  475. package/dist/workspace/review/review-detail.d.ts +10 -0
  476. package/dist/workspace/review/review-detail.js +101 -13
  477. package/dist/workspace/saved-session-skeleton.d.ts +2 -2
  478. package/dist/workspace/saved-session-skeleton.js +3 -3
  479. package/dist/workspace/session-workspace.js +15 -13
  480. package/dist/workspace/sessions/project-sessions-view.js +3 -2
  481. package/dist/workspace/sessions/session-label-badges.js +2 -1
  482. package/dist/workspace/sessions/sessions-toolbar.d.ts +3 -1
  483. package/dist/workspace/sessions/sessions-toolbar.js +2 -2
  484. package/dist/workspace/sidebar/footer/project-apps-nav.d.ts +5 -0
  485. package/dist/workspace/sidebar/footer/project-apps-nav.js +41 -2
  486. package/dist/workspace/sidebar/footer/project-artifacts-nav.d.ts +6 -0
  487. package/dist/workspace/sidebar/footer/project-artifacts-nav.js +22 -0
  488. package/dist/workspace/sidebar/footer/project-chrome-nav.d.ts +10 -0
  489. package/dist/workspace/sidebar/footer/project-chrome-nav.js +56 -0
  490. package/dist/workspace/sidebar/footer/project-manifest-upgrade-alert.js +13 -13
  491. package/dist/workspace/sidebar/footer/project-memory-nav.d.ts +7 -0
  492. package/dist/workspace/sidebar/footer/project-memory-nav.js +19 -0
  493. package/dist/workspace/sidebar/nav-row-meta.js +14 -2
  494. package/dist/workspace/sidebar/project-nav-items.js +3 -0
  495. package/dist/workspace/sidebar/project-session-list.js +68 -56
  496. package/dist/workspace/sidebar/project-sidebar.js +13 -2
  497. package/dist/workspace/sidebar/project-spaces-nav.d.ts +8 -0
  498. package/dist/workspace/sidebar/project-spaces-nav.js +69 -0
  499. package/dist/workspace/sidebar/session-group-order.d.ts +9 -0
  500. package/dist/workspace/sidebar/session-group-order.js +25 -0
  501. package/dist/workspace/sidebar/session-group-sections.d.ts +62 -0
  502. package/dist/workspace/sidebar/session-group-sections.js +267 -0
  503. package/dist/workspace/sidebar/session-list-chrome.d.ts +28 -0
  504. package/dist/workspace/sidebar/session-list-chrome.js +50 -0
  505. package/dist/workspace/spaces/channel-glyph.d.ts +5 -0
  506. package/dist/workspace/spaces/channel-glyph.js +6 -0
  507. package/dist/workspace/spaces/channel-setup.d.ts +16 -0
  508. package/dist/workspace/spaces/channel-setup.js +105 -0
  509. package/dist/workspace/spaces/channels-onboarding.d.ts +13 -0
  510. package/dist/workspace/spaces/channels-onboarding.js +37 -0
  511. package/dist/workspace/spaces/create-channel-dialog.d.ts +16 -0
  512. package/dist/workspace/spaces/create-channel-dialog.js +158 -0
  513. package/dist/workspace/spaces/private-channels-not-in.d.ts +9 -0
  514. package/dist/workspace/spaces/private-channels-not-in.js +69 -0
  515. package/dist/workspace/spaces/space-agents.d.ts +10 -0
  516. package/dist/workspace/spaces/space-agents.js +10 -0
  517. package/dist/workspace/spaces/space-details-dialog.d.ts +20 -0
  518. package/dist/workspace/spaces/space-details-dialog.js +176 -0
  519. package/dist/workspace/spaces/space-link-label.d.ts +49 -0
  520. package/dist/workspace/spaces/space-link-label.js +73 -0
  521. package/dist/workspace/spaces/space-links.d.ts +19 -0
  522. package/dist/workspace/spaces/space-links.js +230 -0
  523. package/dist/workspace/spaces/space-members.d.ts +46 -0
  524. package/dist/workspace/spaces/space-members.js +182 -0
  525. package/dist/workspace/spaces/space-roster.d.ts +15 -0
  526. package/dist/workspace/spaces/space-roster.js +44 -0
  527. package/dist/workspace/spaces/space-threads-tab.d.ts +56 -0
  528. package/dist/workspace/spaces/space-threads-tab.js +156 -0
  529. package/dist/workspace/spaces/space-timeline-view.d.ts +254 -0
  530. package/dist/workspace/spaces/space-timeline-view.js +235 -0
  531. package/dist/workspace/spaces/space-timeline.d.ts +106 -0
  532. package/dist/workspace/spaces/space-timeline.js +183 -0
  533. package/dist/workspace/spaces/space-triggers.d.ts +13 -0
  534. package/dist/workspace/spaces/space-triggers.js +78 -0
  535. package/dist/workspace/spaces/space-view.d.ts +37 -0
  536. package/dist/workspace/spaces/space-view.js +436 -0
  537. package/package.json +67 -36
  538. package/skills/kortix-ui/SKILL.md +3 -3
  539. package/skills/kortix-ui/references/custom-dashboard.md +3 -3
  540. package/skills/kortix-ui/references/modules.md +29 -5
  541. package/skills/kortix-ui/references/theming.md +1 -1
  542. package/dist/customize/connectors/catalog/merge-search.d.ts +0 -10
  543. package/dist/customize/connectors/catalog/merge-search.js +0 -26
  544. package/dist/customize/connectors/detail/find-easy-connect-app.d.ts +0 -29
  545. package/dist/customize/connectors/detail/find-easy-connect-app.js +0 -22
  546. package/dist/customize/migrate-to-v2/use-migrate-to-v2.d.ts +0 -9
  547. package/dist/customize/migrate-to-v2/use-migrate-to-v2.js +0 -24
  548. package/dist/customize/sections/connector-connection-header.d.ts +0 -36
  549. package/dist/customize/sections/connector-connection-header.js +0 -33
  550. package/dist/customize/sections/connector-connection-modal.d.ts +0 -34
  551. package/dist/customize/sections/connector-connection-modal.js +0 -72
  552. package/dist/customize/sections/discover-catalogue-card.d.ts +0 -19
  553. package/dist/customize/sections/discover-catalogue-card.js +0 -26
  554. package/dist/customize/sections/discover-catalogue-detail.d.ts +0 -15
  555. package/dist/customize/sections/discover-catalogue-detail.js +0 -24
  556. package/dist/customize/sections/discover-catalogue.d.ts +0 -17
  557. package/dist/customize/sections/discover-catalogue.js +0 -132
  558. package/dist/customize/sections/llm-provider/provider-access-menu.d.ts +0 -10
  559. package/dist/customize/sections/llm-provider/provider-access-menu.js +0 -23
  560. package/dist/files/project/components/drive-empty-art.d.ts +0 -2
  561. package/dist/files/project/components/drive-empty-art.js +0 -5
  562. package/dist/internal/hooks/use-media-query.d.ts +0 -2
  563. package/dist/internal/share/public-share-link-button.d.ts +0 -14
  564. package/dist/internal/share/public-share-link-button.js +0 -17
  565. package/dist/markdown/setup-links/app-credentials-form.d.ts +0 -12
  566. package/dist/markdown/setup-links/app-credentials-form.js +0 -115
  567. /package/dist/{internal/hooks → hooks}/use-media-query.js +0 -0
@@ -2,18 +2,16 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { Slack } from '../../internal/icons/slack.js';
4
4
  import { useTranslations } from '../../i18n/index.js';
5
- import { CheckIcon as Check, CaretDownIcon as ChevronDown, CaretRightIcon as ChevronRight, CopyIcon as Copy, DotsThreeIcon, ArrowSquareOutIcon as ExternalLink, LockIcon as Lock, EnvelopeIcon as Mail, PlugIcon as Plug, PlusIcon as Plus, MagnifyingGlassIcon as Search, ShareNetworkIcon, UsersIcon as Users, UsersThreeIcon as UsersThree, XIcon as X, LightningIcon as Zap, } from '@phosphor-icons/react';
6
- import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
7
- import { UiImage as Image, useUiViewer, useUiHostConfig } from '../../providers/ui-provider.js';
5
+ import { CheckIcon as Check, CaretDownIcon as ChevronDown, CaretRightIcon as ChevronRight, CopyIcon as Copy, DotsThreeIcon, ArrowSquareOutIcon as ExternalLink, LockIcon as Lock, PlugIcon as Plug, PlusIcon as Plus, ShareNetworkIcon, UsersIcon as Users, UsersThreeIcon as UsersThree, XIcon as X, } from '@phosphor-icons/react';
6
+ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
7
+ import { useUiViewer } from '../../providers/ui-provider.js';
8
8
  import { useEffect, useMemo, useRef, useState } from 'react';
9
9
  import { HighlightedCode } from '../../markdown/code/index.js';
10
10
  import { Badge } from '../../primitives/badge.js';
11
11
  import { Button } from '../../primitives/button.js';
12
12
  import { ButtonGroup, ButtonGroupSeparator } from '../../primitives/button-group.js';
13
- import { Checkbox } from '../../primitives/checkbox.js';
14
13
  import { ConfirmDialog } from '../../primitives/confirm-dialog.js';
15
14
  import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '../../primitives/dropdown-menu.js';
16
- import { EntityAvatar } from '../../primitives/entity-avatar.js';
17
15
  import { Field, FieldDescription, FieldGroup, FieldLabel } from '../../primitives/field.js';
18
16
  import Hint from '../../primitives/hint.js';
19
17
  import { InfoBanner } from '../../primitives/info-banner.js';
@@ -27,36 +25,33 @@ import { Skeleton } from '../../primitives/skeleton.js';
27
25
  import { SplitSheetBody, SplitSheetContent, SplitSheetDescription, SplitSheetFooter, SplitSheetHeader, SplitSheetTitle, } from '../../primitives/split-sheet.js';
28
26
  import { Tabs, TabsContent, TabsList, TabsTrigger } from '../../primitives/tabs.js';
29
27
  import { Textarea } from '../../primitives/textarea.js';
30
- import { errorToast, successToast, warningToast } from '../../primitives/toast.js';
28
+ import { errorToast, successToast } from '../../primitives/toast.js';
31
29
  import { EmptyState } from '../../primitives/empty-state.js';
32
30
  import { ComputerConnectModal, ComputerStateDot } from '../../internal/tunnel/computer-connect.js';
33
31
  import { mcpServerIdentity } from '../connectors/add-mcp/add-mcp-server.js';
34
32
  import { connectorDisplayName } from '../connectors/connector-filter.js';
35
33
  import { isManagedConnectorProvider } from '../connectors/provider-label.js';
36
34
  import { AccessDialog } from '../../access/access/access-dialog.js';
37
- import { useConnectEmail, useConnectSlack, useDisconnectEmail, useDisconnectSlack, useEmailInstall, useEmailMode, useSlackInstall, useSlackManifest, useSlackMode, useUpdateEmailPolicy, } from '../../internal/hooks/channels/use-channels-installations.js';
35
+ import { useConnectSlack, useDisconnectSlack, useSlackInstall, useSlackManifest, useSlackMode, } from '../../internal/hooks/channels/use-channels-installations.js';
38
36
  import { emptyProjectSlot, useAddAccount } from '../../internal/hooks/connectors/use-add-account.js';
39
37
  import { useDeleteTunnelConnection } from '@kortix/sdk/react';
40
38
  import { useCopy } from '../../internal/hooks/use-copy.js';
41
39
  import { cn } from '../../internal/lib/utils.js';
42
- import { createConnector, discoverConnectionOAuth2, discoverConnectionOAuth2Resource, discoverConnectorAuth, ensureProjectConnectorConnection, getConnectorConfig, getConnectStatus, getProjectDetail, listAllConnections, listConnections, listPipedreamApps, listProjectAccess, pollConnectionOAuth2DeviceAuthorization, putConnectionOAuth2Application, reconcileMemberConnection, renameConnection, revokeConnection, setConnectorCredential, setDefaultConnection, startConnectionOAuth2Authorization, startConnectionOAuth2DeviceAuthorization, updateConnectionCredential, } from '@kortix/sdk';
43
- import { contract, qk, useProjectAccountId } from '@kortix/sdk/react';
40
+ import { createConnector, discoverConnectionOAuth2, discoverConnectionOAuth2Resource, discoverConnectorAuth, ensureProjectConnectorConnection, getConnectorConfig, getProjectDetail, listAllConnections, listConnections, listProjectAccess, pollConnectionOAuth2DeviceAuthorization, putConnectionOAuth2Application, reconcileMemberConnection, renameConnection, revokeConnection, setConnectorCredential, setDefaultConnection, startConnectionOAuth2Authorization, startConnectionOAuth2DeviceAuthorization, updateConnectionCredential, } from '@kortix/sdk';
41
+ import { contract, qk, useFeatureFlag, useProjectAccountId } from '@kortix/sdk/react';
44
42
  import { AddAccountFields } from './add-account-fields.js';
45
- import { buildEasyConnectConnectorDraft, buildEmailConnectorConnectionSlug, connectorSyncErrorForSlug, createOnlyConnectorDraft, proposeConnectorConnectionSlug, } from './connector-connection-form.js';
46
- import { ConnectorConnectionModal } from './connector-connection-modal.js';
43
+ import { useEmailInboxes, useRemoveEmailInbox, } from '../../internal/hooks/channels/use-email-inboxes.js';
44
+ import { AddEmailInboxDialog, EMAIL_CONNECTOR_SLUG, EmailInboxHome, EmailSenderPolicyDialog, } from '../connectors/detail/email-inboxes.js';
47
45
  import { credentialWriteTarget, oauth2DiscoveryConnectionKey } from './connector-credential-target.js';
48
46
  import { buildOAuth2ApplicationInput, buildOAuth2CredentialInput, EMPTY_OAUTH2_APPLICATION_FORM, EMPTY_OAUTH2_CREDENTIAL_FORM, mergeOAuth2DiscoveryMetadata, oauth2ApplicationFormValid, oauth2CredentialFormValid, } from './connector-oauth2.js';
49
47
  import { OAuth2ApplicationFields } from './connector-oauth2-application-fields.js';
50
48
  import { autoConnectPlan, mergeResourceDiscoveryIntoForm } from './connector-oauth2-auto.js';
51
49
  import { OAuth2CredentialFields } from './connector-oauth2-fields.js';
52
50
  import { startOAuth2SignIn } from './connector-oauth2-start.js';
53
- import { DiscoverCatalogue } from './discover-catalogue.js';
54
51
  import { useAddRequest } from './use-add-request.js';
55
52
  import { useCreateCustomConnector } from './use-create-custom-connector.js';
56
53
  import { AudienceText } from './view/audience-badge.js';
57
54
  import { accountNeedsSignIn, accountVisibility, connectorConnectionRows, newAccountLabelTaken, newAccountReady, } from './view/connector-connections.js';
58
- import { randomUUID } from '../../internal/lib/utils/random-uuid.js';
59
- const BUILT_IN_CHANNEL_APP_SLUGS = new Set(['slack', 'slack_v2']);
60
55
  function SaveBar({ dirty, saving, disabled, onSave, onReset, label = 'Save', }) {
61
56
  const tI18nHardcoded = useTranslations('hardcodedUi');
62
57
  if (!dirty)
@@ -67,7 +62,7 @@ function CodeSnippet({ code, language, className, }) {
67
62
  return (_jsx("div", { className: cn('border-border/60 bg-card flex w-full overflow-x-auto rounded-md border', className), children: _jsx("div", { className: "p-3 [&_code]:text-xs", children: _jsx(HighlightedCode, { code: code, language: language }) }) }));
68
63
  }
69
64
  /** One row in the connections list — a single connected account. */
70
- function ConnectionRow({ connection, viewerId, isMine, canManage, onSetDefault, onDisconnect, onRename, onStartSession, onSetCredential, onShare, onConnect, needsSignIn, pending, disabled = false, }) {
65
+ function ConnectionRow({ connection, viewerId, isMine, canManage, onSetDefault, onDisconnect, onRename, onStartSession, onSetCredential, onShare, onConnect, needsSignIn, pending, disabled = false, meta, menuItems, }) {
71
66
  const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
72
67
  const tSharing = useTranslations('accessSharing');
73
68
  const tComputers = useTranslations('computers');
@@ -80,12 +75,12 @@ function ConnectionRow({ connection, viewerId, isMine, canManage, onSetDefault,
80
75
  const visibility = accountVisibility(connection, viewerId);
81
76
  const everyoneWithAccess = (connection.shared_with ?? []).map((share) => share.label);
82
77
  const { copy } = useCopy({ successMessage: tI18nComplete.raw('text56ee71f3ece0') });
83
- return (_jsxs("li", { className: "flex items-center gap-3 px-4 py-3", children: [_jsx("span", { "aria-hidden": true, className: "bg-muted text-muted-foreground flex size-8 shrink-0 items-center justify-center rounded-md", children: visibility.kind === 'you' ? (_jsx(Lock, { className: "size-4" })) : visibility.kind === 'everyone' ? (_jsx(UsersThree, { className: "size-4" })) : (_jsx(Users, { className: "size-4" })) }), _jsxs("div", { className: "min-w-0 flex-1 space-y-0.5", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-1.5", children: [_jsx("span", { className: "truncate text-sm font-medium", children: connection.label }), connection.is_default && (_jsx(Badge, { variant: "secondary", size: "xs", children: tI18nComplete.raw('text21b111cbfe6e') }))] }), _jsxs(InlineMeta, { children: [_jsx(AudienceText, { visibility: visibility, labels: everyoneWithAccess }), connection.usable === false ? tSharing('notSharedWithYou') : null, active && needsSignIn ? (_jsx("span", { children: tConnectorPages('notSignedIn') })) : null, active && connection.metadata?.credential_rejected_at ? (_jsx("span", { className: "text-destructive", children: tConnectorPages('credentialRejected') })) : null, active ? null : (_jsx("span", { className: "text-destructive", children: connection.status === 'revoked' ? 'Disconnected' : 'Error' })), active && connection.machine ? (_jsxs("span", { className: "inline-flex items-center gap-1.5", children: [_jsx(ComputerStateDot, { state: connection.machine.online ? 'online' : 'offline' }), tComputers(connection.machine.online ? 'online' : 'offline')] })) : null, connection.connected_as && connection.connected_as !== connection.label
78
+ return (_jsxs("li", { className: "flex items-center gap-3 px-4 py-3", children: [_jsx("span", { "aria-hidden": true, className: "bg-muted text-muted-foreground flex size-8 shrink-0 items-center justify-center rounded-md", children: visibility.kind === 'you' ? (_jsx(Lock, { className: "size-4" })) : visibility.kind === 'everyone' ? (_jsx(UsersThree, { className: "size-4" })) : (_jsx(Users, { className: "size-4" })) }), _jsxs("div", { className: "min-w-0 flex-1 space-y-0.5", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-1.5", children: [_jsx("span", { className: "truncate text-sm font-medium", children: connection.label }), connection.is_default && (_jsx(Badge, { variant: "secondary", size: "xs", children: tI18nComplete.raw('text21b111cbfe6e') }))] }), _jsxs(InlineMeta, { children: [_jsx(AudienceText, { visibility: visibility, labels: everyoneWithAccess }), meta, connection.usable === false ? tSharing('notSharedWithYou') : null, active && needsSignIn ? (_jsx("span", { children: tConnectorPages('notSignedIn') })) : null, active && connection.metadata?.credential_rejected_at ? (_jsx("span", { className: "text-destructive", children: tConnectorPages('credentialRejected') })) : null, active ? null : (_jsx("span", { className: "text-destructive", children: connection.status === 'revoked' ? 'Disconnected' : 'Error' })), active && connection.machine ? (_jsxs("span", { className: "inline-flex items-center gap-1.5", children: [_jsx(ComputerStateDot, { state: connection.machine.online ? 'online' : 'offline' }), tComputers(connection.machine.online ? 'online' : 'offline')] })) : null, connection.connected_as && connection.connected_as !== connection.label
84
79
  ? tI18nComplete('texte9e0b20cf289', { value0: connection.connected_as })
85
80
  : null] })] }), onConnect && mayMutate && needsSignIn ? (_jsx(Button, { size: "sm", className: "shrink-0", onClick: onConnect, disabled: pending || disabled, children: tConnectorPages('connectAccount') })) : null, _jsxs(ButtonGroup, { className: "shrink-0", children: [onShare && mayMutate ? (
86
81
  // Your own private account is shared by turning it into a shared one,
87
82
  // which needs the same right as creating a shared account.
88
- isProjectAuthorization || canManage ? (_jsxs(Button, { variant: "secondary", size: "sm", className: "shrink-0 gap-1.5", onClick: onShare, disabled: pending || disabled, "aria-label": tSharing('shareTitle', { label: connection.label }), children: [_jsx(ShareNetworkIcon, { className: "size-3.5 shrink-0" }), tI18nComplete.raw('text29887a5ff984')] })) : (_jsx(Hint, { label: tSharing('shareRequiresManage'), children: _jsx("span", { className: "inline-flex shrink-0", children: _jsxs(Button, { variant: "secondary", size: "sm", className: "gap-1.5", disabled: true, "aria-label": tSharing('shareTitle', { label: connection.label }), children: [_jsx(ShareNetworkIcon, { className: "size-3.5 shrink-0" }), tI18nComplete.raw('text29887a5ff984')] }) }) }))) : null, _jsx(ButtonGroupSeparator, { className: "bg-border" }), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "secondary", size: "icon", className: "size-8 shrink-0", "aria-label": tI18nComplete('text33da220b1a34', { value0: connection.label }), disabled: pending || disabled, children: pending ? (_jsx(Loading, { className: "size-4 shrink-0" })) : (_jsx(DotsThreeIcon, { className: "size-4" })) }) }), _jsxs(DropdownMenuContent, { align: "end", className: "min-w-48", children: [_jsx(DropdownMenuItem, { onClick: () => copy(connection.connection_id), children: tI18nComplete.raw('text99775327d988') }), mayMutate && (_jsx(DropdownMenuItem, { onClick: onRename, children: tI18nComplete.raw('text3064d79a295c') })), mayMutate && isMine && active && onStartSession && (_jsx(DropdownMenuItem, { onClick: onStartSession, children: tI18nComplete.raw('textfae237eed0c5') })), mayMutate && onSetCredential && (_jsx(DropdownMenuItem, { onClick: onSetCredential, children: tI18nComplete.raw('text3d6627454174') })), mayMutate && !connection.is_default && active && (_jsxs(DropdownMenuItem, { onClick: onSetDefault, children: [tI18nComplete.raw('texta92f66fd3d83'), isProjectAuthorization ? ` ${tI18nComplete.raw('text801a345cd406')}` : ''] })), mayMutate && (_jsx(DropdownMenuItem, { onClick: onDisconnect, children: tI18nComplete.raw('textacfc5be785a9') }))] })] })] })] }));
83
+ isProjectAuthorization || canManage ? (_jsxs(Button, { variant: "secondary", size: "sm", className: "shrink-0 gap-1.5", onClick: onShare, disabled: pending || disabled, "aria-label": tSharing('shareTitle', { label: connection.label }), children: [_jsx(ShareNetworkIcon, { className: "size-3.5 shrink-0" }), tI18nComplete.raw('text29887a5ff984')] })) : (_jsx(Hint, { label: tSharing('shareRequiresManage'), children: _jsx("span", { className: "inline-flex shrink-0", children: _jsxs(Button, { variant: "secondary", size: "sm", className: "gap-1.5", disabled: true, "aria-label": tSharing('shareTitle', { label: connection.label }), children: [_jsx(ShareNetworkIcon, { className: "size-3.5 shrink-0" }), tI18nComplete.raw('text29887a5ff984')] }) }) }))) : null, _jsx(ButtonGroupSeparator, { className: "bg-border" }), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "secondary", size: "icon", className: "size-8 shrink-0", "aria-label": tI18nComplete('text33da220b1a34', { value0: connection.label }), disabled: pending || disabled, children: pending ? (_jsx(Loading, { className: "size-4 shrink-0" })) : (_jsx(DotsThreeIcon, { className: "size-4" })) }) }), _jsxs(DropdownMenuContent, { align: "end", className: "min-w-48", children: [_jsx(DropdownMenuItem, { onClick: () => copy(connection.connection_id), children: tI18nComplete.raw('text99775327d988') }), mayMutate && (_jsx(DropdownMenuItem, { onClick: onRename, children: tI18nComplete.raw('text3064d79a295c') })), mayMutate && isMine && active && onStartSession && (_jsx(DropdownMenuItem, { onClick: onStartSession, children: tI18nComplete.raw('textfae237eed0c5') })), mayMutate && onSetCredential && (_jsx(DropdownMenuItem, { onClick: onSetCredential, children: tI18nComplete.raw('text3d6627454174') })), mayMutate && !connection.is_default && active && (_jsxs(DropdownMenuItem, { onClick: onSetDefault, children: [tI18nComplete.raw('texta92f66fd3d83'), isProjectAuthorization ? ` ${tI18nComplete.raw('text801a345cd406')}` : ''] })), mayMutate ? menuItems : null, mayMutate && (_jsx(DropdownMenuItem, { onClick: onDisconnect, children: tI18nComplete.raw('textacfc5be785a9') }))] })] })] })] }));
89
84
  }
90
85
  /**
91
86
  * Every account this connector can run as, in one list. Each card states who
@@ -118,8 +113,17 @@ export function ConnectionsList({ projectId, connector, displayName, canManageCo
118
113
  // A computer account is a paired machine: "Add" pairs one (desktop one-click,
119
114
  // or download + npx) instead of asking for a credential.
120
115
  const isComputer = connector.provider === 'computer';
121
- const isDirectProvider = !isManagedConnectorProvider(connector.provider) && !isComputer;
116
+ // An email account is an inbox: "Add" creates one (own Resend key or Kortix
117
+ // managed), and removing it deletes the inbox Kortix made.
118
+ const isEmail = connector.provider === 'channel' && connector.platform === 'email';
119
+ const isDirectProvider = !isManagedConnectorProvider(connector.provider) && !isComputer && !isEmail;
122
120
  const [computerOpen, setComputerOpen] = useState(false);
121
+ const [emailOpen, setEmailOpen] = useState(false);
122
+ const [policyInbox, setPolicyInbox] = useState(null);
123
+ const tInboxes = useTranslations('emailInboxes');
124
+ const inboxesQuery = useEmailInboxes(isEmail ? projectId : null);
125
+ const inboxByConnection = new Map((inboxesQuery.data ?? []).map((inbox) => [inbox.connection_id, inbox]));
126
+ const removeInbox = useRemoveEmailInbox();
123
127
  const user = useUiViewer();
124
128
  const viewerId = user?.id ?? null;
125
129
  const [confirmDisconnect, setConfirmDisconnect] = useState(null);
@@ -148,13 +152,16 @@ export function ConnectionsList({ projectId, connector, displayName, canManageCo
148
152
  });
149
153
  const refresh = () => {
150
154
  void connectionsQuery.refetch();
155
+ if (isEmail)
156
+ void inboxesQuery.refetch();
151
157
  onChanged();
152
158
  };
153
159
  const allRows = connectorConnectionRows(connectionsQuery.data?.connections, connector.slug);
154
160
  // The server's empty shared slot is a placeholder, not an account anyone
155
161
  // added: listing it reads as "everyone already shares this". Add account
156
162
  // still reuses it when the person picks Everyone.
157
- const slot = emptyProjectSlot(connector, allRows);
163
+ // An inbox account always has an inbox behind it: there is no empty slot.
164
+ const slot = isEmail ? null : emptyProjectSlot(connector, allRows);
158
165
  const rows = slot ? allRows.filter((row) => row !== slot) : allRows;
159
166
  const openCredential = onSetCredential ?? setCredentialTarget;
160
167
  // "Add account" asks the account's name and who may use it: only you,
@@ -183,6 +190,10 @@ export function ConnectionsList({ projectId, connector, displayName, canManageCo
183
190
  setComputerOpen(true);
184
191
  return;
185
192
  }
193
+ if (isEmail) {
194
+ setEmailOpen(true);
195
+ return;
196
+ }
186
197
  setDraft({ ...EMPTY_NEW_ACCOUNT, label: addAccount.proposedLabel() });
187
198
  setLabelEdited(false);
188
199
  setAddOpen(true);
@@ -244,11 +255,13 @@ export function ConnectionsList({ projectId, connector, displayName, canManageCo
244
255
  };
245
256
  const pendingConnectionId = setDefault.isPending && typeof setDefault.variables === 'string'
246
257
  ? setDefault.variables
247
- : disconnect.isPending && typeof disconnect.variables === 'string'
248
- ? disconnect.variables
249
- : rename.isPending && rename.variables
250
- ? rename.variables.connectionId
251
- : null;
258
+ : removeInbox.isPending && removeInbox.variables
259
+ ? removeInbox.variables.connectionId
260
+ : disconnect.isPending && typeof disconnect.variables === 'string'
261
+ ? disconnect.variables
262
+ : rename.isPending && rename.variables
263
+ ? rename.variables.connectionId
264
+ : null;
252
265
  // Re-open the credential entry for an existing direct-provider account —
253
266
  // wired from the row menu ("Set credential") and reused right after
254
267
  // `useAddAccount` creates a brand new one.
@@ -261,12 +274,24 @@ export function ConnectionsList({ projectId, connector, displayName, canManageCo
261
274
  // A member's computer account follows them into every project, so it is
262
275
  // never removed from one project: Disconnect unpairs the machine.
263
276
  const ownComputer = (connection) => isComputer && connection.owner_type === 'member';
264
- const renderRow = (connection) => (_jsx(ConnectionRow, { connection: connection, viewerId: viewerId, isMine: connection.owner_type === 'member', canManage: canManageConnections, pending: pendingConnectionId === connection.connection_id, disabled: disabled, onSetDefault: () => setDefault.mutate(connection.connection_id), onDisconnect: () => setConfirmDisconnect(connection), onRename: () => openRename(connection), onStartSession: onStartSession ? () => onStartSession(connection) : undefined, onSetCredential: setCredential ? () => setCredential(connection) : undefined, onConnect: onConnect ? () => onConnect(connection) : undefined, needsSignIn: accountNeedsSignIn(connection, connector), onShare: accountId
265
- ? () => {
266
- setShareTarget(connection);
267
- setShareOpen(true);
268
- }
269
- : undefined }, connection.connection_id));
277
+ const renderRow = (connection) => {
278
+ const inbox = isEmail ? inboxByConnection.get(connection.connection_id) : undefined;
279
+ return (_jsx(ConnectionRow, { connection: connection,
280
+ // An array, not a fragment: InlineMeta separates its children, and a
281
+ // fragment is one child (address and home ran together).
282
+ meta: inbox
283
+ ? [
284
+ inbox.email !== connection.label ? _jsx("span", { children: inbox.email }, "address") : null,
285
+ _jsx(EmailInboxHome, { inbox: inbox }, "home"),
286
+ ]
287
+ : undefined, menuItems: inbox ? (_jsx(DropdownMenuItem, { onClick: () => setPolicyInbox(inbox), children: tInboxes('policyMenu') })) : undefined, viewerId: viewerId, isMine: connection.owner_type === 'member', canManage: canManageConnections, pending: pendingConnectionId === connection.connection_id, disabled: disabled, onSetDefault: () => setDefault.mutate(connection.connection_id), onDisconnect: () => setConfirmDisconnect(connection), onRename: () => openRename(connection), onStartSession: onStartSession ? () => onStartSession(connection) : undefined, onSetCredential: setCredential ? () => setCredential(connection) : undefined, onConnect: onConnect ? () => onConnect(connection) : undefined, needsSignIn: !isEmail && accountNeedsSignIn(connection, connector), onShare: accountId
288
+ ? () => {
289
+ setShareTarget(connection);
290
+ setShareOpen(true);
291
+ }
292
+ : undefined }, connection.connection_id));
293
+ };
294
+ const confirmInbox = confirmDisconnect && isEmail ? inboxByConnection.get(confirmDisconnect.connection_id) : undefined;
270
295
  return (_jsxs("div", { className: "space-y-6", children: [_jsxs("section", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [titleAddon ? (_jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Label, { children: tSharing('accountsTitle') }), titleAddon] })) : (_jsx(Label, { children: tSharing('accountsTitle') })), isComputer ? (_jsxs(Button, { size: "sm", variant: addVariant, onClick: () => setComputerOpen(true), disabled: disabled, children: [_jsx(Plus, { className: "size-4" }), tSharing('addAccount')] })) : (_jsxs(Button, { size: "sm", variant: addVariant, onClick: openAdd, disabled: disabled, children: [_jsx(Plus, { className: "size-4" }), tSharing('addAccount')] }))] }), connectionsQuery.isLoading ? (_jsxs("div", { className: "space-y-2", children: [_jsx(Skeleton, { className: "h-14 rounded-md" }), _jsx(Skeleton, { className: "h-14 rounded-md" })] })) : rows.length === 0 ? (_jsx(EmptyState, { size: "sm", icon: Plug, title: tSharing('noAccountsTitle'), description: tSharing('noAccountsDescription', { connector: displayName }) })) : (_jsx("ul", { className: "bg-popover divide-border divide-y rounded-md border", children: rows.map(renderRow) }))] }), accountId && shareTarget ? (_jsx(AccessDialog, { open: shareOpen, onOpenChange: setShareOpen, accountId: accountId, scope: { kind: 'project', projectId, projectName }, mode: {
271
296
  kind: 'share',
272
297
  object: {
@@ -295,13 +320,28 @@ export function ConnectionsList({ projectId, connector, displayName, canManageCo
295
320
  }, children: _jsxs(ModalContent, { className: "lg:max-w-md", children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { children: tI18nComplete('textbb7a240d3660', { value0: renameTarget?.label ?? '' }) }), _jsx(ModalDescription, { children: tI18nComplete.raw('text64f07c825803') })] }), _jsxs("form", { onSubmit: (e) => {
296
321
  e.preventDefault();
297
322
  submitRename();
298
- }, children: [_jsx(ModalBody, { children: _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "connection-rename-label", children: tI18nComplete.raw('textdcd1d5223f73') }), _jsx(Input, { id: "connection-rename-label", value: renameDraft, onChange: (e) => setRenameDraft(e.target.value), maxLength: 255, autoFocus: true, disabled: rename.isPending || disabled }), renameTarget?.connected_as ? (_jsx(FieldDescription, { children: tI18nComplete('texte9e0b20cf289', { value0: renameTarget.connected_as }) })) : null] }) }), _jsxs(ModalFooter, { className: "sm:justify-between", children: [_jsx(Button, { type: "button", variant: "outline-ghost", onClick: () => setRenameTarget(null), disabled: rename.isPending, children: tI18nComplete.raw('text19766ed6ccb2') }), _jsxs(Button, { type: "submit", disabled: rename.isPending || disabled || !renameDraft.trim(), children: [rename.isPending ? _jsx(Loading, { className: "size-4 shrink-0" }) : null, tI18nComplete.raw('text1509f561f241')] })] })] })] }) }), _jsx(ConfirmDialog, { open: confirmDisconnect !== null, onOpenChange: (open) => !open && setConfirmDisconnect(null), title: tI18nComplete('text13716a578591', { value0: confirmDisconnect?.label ?? '' }), description: confirmDisconnect && ownComputer(confirmDisconnect)
299
- ? tComputers('unpairDescription')
300
- : confirmDisconnect?.owner_type === 'project'
301
- ? tI18nComplete.raw('texte2cbafcec553')
302
- : tI18nComplete.raw('text64db32d83da9'), confirmLabel: tI18nComplete.raw('textacfc5be785a9'), confirmVariant: "destructive", isPending: disconnect.isPending || unpairComputer.isPending, onConfirm: () => {
323
+ }, children: [_jsx(ModalBody, { children: _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "connection-rename-label", children: tI18nComplete.raw('textdcd1d5223f73') }), _jsx(Input, { id: "connection-rename-label", value: renameDraft, onChange: (e) => setRenameDraft(e.target.value), maxLength: 255, autoFocus: true, disabled: rename.isPending || disabled }), renameTarget?.connected_as ? (_jsx(FieldDescription, { children: tI18nComplete('texte9e0b20cf289', { value0: renameTarget.connected_as }) })) : null] }) }), _jsxs(ModalFooter, { className: "sm:justify-between", children: [_jsx(Button, { type: "button", variant: "outline-ghost", onClick: () => setRenameTarget(null), disabled: rename.isPending, children: tI18nComplete.raw('text19766ed6ccb2') }), _jsxs(Button, { type: "submit", disabled: rename.isPending || disabled || !renameDraft.trim(), children: [rename.isPending ? _jsx(Loading, { className: "size-4 shrink-0" }) : null, tI18nComplete.raw('text1509f561f241')] })] })] })] }) }), _jsx(ConfirmDialog, { open: confirmDisconnect !== null, onOpenChange: (open) => !open && setConfirmDisconnect(null), title: tI18nComplete('text13716a578591', { value0: confirmDisconnect?.label ?? '' }), description: confirmInbox
324
+ ? confirmInbox.created_by_kortix
325
+ ? tInboxes('removeDeletes', { address: confirmInbox.email })
326
+ : tInboxes('removeKeeps', { address: confirmInbox.email })
327
+ : confirmDisconnect && ownComputer(confirmDisconnect)
328
+ ? tComputers('unpairDescription')
329
+ : confirmDisconnect?.owner_type === 'project'
330
+ ? tI18nComplete.raw('texte2cbafcec553')
331
+ : tI18nComplete.raw('text64db32d83da9'), confirmLabel: tI18nComplete.raw('textacfc5be785a9'), confirmVariant: "destructive", isPending: disconnect.isPending || unpairComputer.isPending || removeInbox.isPending, onConfirm: () => {
303
332
  if (!confirmDisconnect)
304
333
  return;
334
+ if (isEmail) {
335
+ removeInbox.mutate({ projectId, connectionId: confirmDisconnect.connection_id }, {
336
+ onSuccess: () => {
337
+ successToast(tInboxes('removed'));
338
+ setConfirmDisconnect(null);
339
+ refresh();
340
+ },
341
+ onError: (e) => errorToast(e.message || tI18nComplete.raw('textb7668a581f59')),
342
+ });
343
+ return;
344
+ }
305
345
  if (ownComputer(confirmDisconnect) && confirmDisconnect.tunnel_id) {
306
346
  unpairComputer.mutate(confirmDisconnect.tunnel_id, {
307
347
  onSuccess: () => {
@@ -314,7 +354,7 @@ export function ConnectionsList({ projectId, connector, displayName, canManageCo
314
354
  return;
315
355
  }
316
356
  disconnect.mutate(confirmDisconnect.connection_id);
317
- } }), isComputer ? (_jsx(ComputerConnectModal, { projectId: projectId, open: computerOpen, onOpenChange: setComputerOpen, onConnected: refresh })) : null, isDirectProvider && !onSetCredential ? (_jsx(SetCredentialModal, { projectId: projectId, connector: credentialTarget ? connector : null, connectionId: credentialTarget?.connectionId ?? null, owner: credentialTarget?.owner ?? 'me', open: credentialTarget !== null, onOpenChange: (open) => {
357
+ } }), isEmail ? (_jsxs(_Fragment, { children: [_jsx(AddEmailInboxDialog, { projectId: projectId, open: emailOpen, onOpenChange: setEmailOpen, existing: rows, onAdded: refresh }), _jsx(EmailSenderPolicyDialog, { projectId: projectId, inbox: policyInbox, open: policyInbox !== null, onOpenChange: (open) => !open && setPolicyInbox(null) })] })) : null, isComputer ? (_jsx(ComputerConnectModal, { projectId: projectId, open: computerOpen, onOpenChange: setComputerOpen, onConnected: refresh })) : null, isDirectProvider && !onSetCredential ? (_jsx(SetCredentialModal, { projectId: projectId, connector: credentialTarget ? connector : null, connectionId: credentialTarget?.connectionId ?? null, owner: credentialTarget?.owner ?? 'me', open: credentialTarget !== null, onOpenChange: (open) => {
318
358
  if (!open)
319
359
  setCredentialTarget(null);
320
360
  }, onSaved: () => {
@@ -365,171 +405,18 @@ function connectorPlatform(connector) {
365
405
  }
366
406
  if (connector.slug === 'kortix_slack')
367
407
  return 'slack';
368
- if (connector.slug === 'kortix_email')
369
- return 'email';
370
- if (connector.slug.startsWith('email_'))
408
+ if (connector.slug === EMAIL_CONNECTOR_SLUG)
371
409
  return 'email';
372
410
  return null;
373
411
  }
374
412
  export function ChannelConnectionSection({ projectId, connector, onChanged, onRemoved, canWrite = false, }) {
375
413
  const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
376
414
  const platform = connectorPlatform(connector);
377
- if (platform === 'email') {
378
- return (_jsx(EmailChannelConnection, { projectId: projectId, connector: connector, onChanged: onChanged, onRemoved: onRemoved, canWrite: canWrite }));
379
- }
380
415
  if (platform === 'slack') {
381
416
  return (_jsx(SlackChannelConnection, { projectId: projectId, onChanged: onChanged, onRemoved: onRemoved, canWrite: canWrite }));
382
417
  }
383
418
  return (_jsxs("section", { className: "space-y-4", children: [_jsx(Label, { children: tI18nComplete.raw('text639a40e82b9a') }), _jsx("div", { className: "bg-popover rounded-md border px-4 py-3", children: _jsx(InfoBanner, { tone: "warning", children: tI18nComplete.raw('text53f76274b923') }) })] }));
384
419
  }
385
- function EmailChannelConnection({ projectId, connector, onChanged, onRemoved, canWrite = false, }) {
386
- const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
387
- const install = useEmailInstall(projectId, connector.slug);
388
- return (_jsxs("section", { className: "space-y-4", children: [_jsx(Label, { children: tI18nComplete.raw('text7033ce3d1e7a') }), _jsx("p", { className: "text-muted-foreground -mt-2 text-xs", children: tI18nComplete.raw('text28d1c949e5e6') }), _jsx("div", { className: "bg-popover rounded-md border px-4 py-3", children: install.isLoading ? (_jsx(Skeleton, { className: "h-24 w-full rounded-md" })) : install.data ? (_jsx(ConnectedEmailConnection, { projectId: projectId, connectorSlug: connector.slug, installation: install.data, onRemoved: onRemoved, canWrite: canWrite })) : canWrite ? (_jsx(EmailConnectForm, { projectId: projectId, connectorSlug: connector.slug, onConnected: onChanged })) : (_jsx(InfoBanner, { tone: "neutral", icon: Mail, title: tI18nComplete.raw('textf0aea4d97b8e'), children: tI18nComplete.raw('text2dec6c273b47') })) })] }));
389
- }
390
- function ConnectedEmailConnection({ projectId, connectorSlug, installation, onRemoved, canWrite = false, }) {
391
- const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
392
- const disconnect = useDisconnectEmail();
393
- const [confirming, setConfirming] = useState(false);
394
- return (_jsxs("div", { className: "space-y-4", children: [_jsxs(InfoBanner, { tone: "success", icon: Check, title: tI18nComplete.raw('textc23cc1f72afe'), children: [tI18nComplete.raw('text56ef8f20955f'), ' ', _jsx("code", { className: "font-mono", children: installation.email }), ' · ', tI18nComplete.raw('text94835ea2fcf7'), ' ', _jsx("code", { className: "font-mono", children: installation.inboxId }), installation.webhookId ? (_jsxs(_Fragment, { children: [' · ', tI18nComplete.raw('text4814f62c108d'), ' ', _jsx("code", { className: "font-mono", children: installation.webhookId })] })) : null] }), _jsx(EmailSenderPolicyEditor, { projectId: projectId, connectorSlug: connectorSlug, policy: installation.senderPolicy, canWrite: canWrite }), canWrite && (_jsx("div", { className: "flex items-center justify-end gap-2", children: confirming ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-muted-foreground mr-auto text-xs", children: tI18nComplete.raw('text2a528ae2d4ae') }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => setConfirming(false), children: tI18nComplete.raw('text19766ed6ccb2') }), _jsxs(Button, { variant: "destructive", size: "sm", disabled: disconnect.isPending, onClick: () => disconnect.mutate({ projectId, connectorSlug }, {
395
- onSuccess: () => {
396
- setConfirming(false);
397
- onRemoved();
398
- },
399
- }), children: [disconnect.isPending ? _jsx(Loading, { className: "mr-2 size-3.5 shrink-0" }) : null, tI18nComplete.raw('textacfc5be785a9')] })] })) : (_jsx(Button, { variant: "outline", size: "sm", onClick: () => setConfirming(true), children: tI18nComplete.raw('textacfc5be785a9') })) }))] }));
400
- }
401
- function splitPolicyList(value) {
402
- return Array.from(new Set(value
403
- .split(/[\n,]+/)
404
- .map((item) => item.trim().toLowerCase())
405
- .filter(Boolean)));
406
- }
407
- function normalizeEmailSenderPolicy(policy) {
408
- return {
409
- mode: policy?.mode === 'restricted' ? 'restricted' : 'allow_all',
410
- allowedEmails: policy?.allowedEmails ?? [],
411
- allowedDomains: policy?.allowedDomains ?? [],
412
- allowedRegex: policy?.allowedRegex ?? null,
413
- };
414
- }
415
- function EmailSenderPolicyEditor({ projectId, connectorSlug, policy, canWrite = false, }) {
416
- const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
417
- const update = useUpdateEmailPolicy();
418
- const initial = normalizeEmailSenderPolicy(policy);
419
- const [restricted, setRestricted] = useState(initial.mode === 'restricted');
420
- const [emails, setEmails] = useState(() => initial.allowedEmails.join('\n'));
421
- const [domains, setDomains] = useState(() => initial.allowedDomains.join('\n'));
422
- const [regex, setRegex] = useState(initial.allowedRegex ?? '');
423
- const [error, setError] = useState(null);
424
- const [syncedPolicy, setSyncedPolicy] = useState(policy);
425
- if (policy !== syncedPolicy) {
426
- setSyncedPolicy(policy);
427
- const next = normalizeEmailSenderPolicy(policy);
428
- setRestricted(next.mode === 'restricted');
429
- setEmails(next.allowedEmails.join('\n'));
430
- setDomains(next.allowedDomains.join('\n'));
431
- setRegex(next.allowedRegex ?? '');
432
- setError(null);
433
- }
434
- const nextPolicy = () => ({
435
- mode: restricted ? 'restricted' : 'allow_all',
436
- allowedEmails: splitPolicyList(emails),
437
- allowedDomains: splitPolicyList(domains).map((domain) => domain.replace(/^@+/, '')),
438
- allowedRegex: regex.trim() || null,
439
- });
440
- const save = () => {
441
- setError(null);
442
- const sender_policy = nextPolicy();
443
- if (sender_policy.allowedRegex) {
444
- try {
445
- new RegExp(sender_policy.allowedRegex);
446
- }
447
- catch {
448
- setError('Regex is invalid');
449
- return;
450
- }
451
- }
452
- update.mutate({ projectId, connectorSlug, sender_policy }, { onError: (e) => setError(e.message) });
453
- };
454
- const dirty = restricted !== (initial.mode === 'restricted') ||
455
- emails !== initial.allowedEmails.join('\n') ||
456
- domains !== initial.allowedDomains.join('\n') ||
457
- regex !== (initial.allowedRegex ?? '');
458
- return (_jsx("div", { className: "border-border/60 bg-card rounded-md border p-4", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(Checkbox, { id: "email-sender-restricted", checked: restricted, onCheckedChange: (checked) => setRestricted(Boolean(checked)), className: "mt-0.5", disabled: !canWrite }), _jsxs("div", { className: "min-w-0 flex-1 space-y-3", children: [_jsxs("div", { children: [_jsx(Label, { htmlFor: "email-sender-restricted", children: tI18nComplete.raw('texta48c89f63885') }), _jsx("p", { className: "text-muted-foreground mt-1 text-xs", children: tI18nComplete.raw('text8c67b476d59b') })] }), restricted ? (_jsxs("div", { className: "grid gap-3 sm:grid-cols-2", children: [_jsx(Field, { children: _jsx(Input, { value: emails, onChange: (e) => setEmails(e.target.value), placeholder: tI18nComplete.raw('text542d24012988'), disabled: !canWrite }) }), _jsx(Field, { children: _jsx(Input, { value: domains, onChange: (e) => setDomains(e.target.value), placeholder: tI18nComplete.raw('texta379a6f6eeaf'), disabled: !canWrite }) }), _jsx("div", { className: "sm:col-span-2", children: _jsx(Field, { children: _jsx(Input, { value: regex, onChange: (e) => setRegex(e.target.value), placeholder: tI18nComplete.raw('text8b21058f3253'), spellCheck: false, disabled: !canWrite }) }) })] })) : null, error ? _jsx(InfoBanner, { tone: "destructive", children: error }) : null, canWrite && (_jsx(SaveBar, { dirty: dirty, saving: update.isPending, onSave: save, onReset: () => {
459
- setRestricted(initial.mode === 'restricted');
460
- setEmails(initial.allowedEmails.join('\n'));
461
- setDomains(initial.allowedDomains.join('\n'));
462
- setRegex(initial.allowedRegex ?? '');
463
- }, label: tI18nComplete.raw('text57ee14ce1425') }))] })] }) }));
464
- }
465
- export function EmailConnectForm({ projectId, connectorSlug, onConnected, }) {
466
- const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
467
- const mode = useEmailMode(projectId);
468
- const connect = useConnectEmail();
469
- const [displayName, setDisplayName] = useState('Kortix Agent');
470
- const [username, setUsername] = useState(() => connectorSlug
471
- .replace(/^email_/, '')
472
- .replace(/_[a-z0-9]{4}$/i, '')
473
- .replace(/_/g, '-'));
474
- const [attachExisting, setAttachExisting] = useState(false);
475
- const [existingInboxId, setExistingInboxId] = useState('');
476
- const [existingEmail, setExistingEmail] = useState('');
477
- const [apiKey, setApiKey] = useState('');
478
- const [customKeyOpen, setCustomKeyOpen] = useState(false);
479
- const [restricted, setRestricted] = useState(false);
480
- const [emails, setEmails] = useState('');
481
- const [domains, setDomains] = useState('');
482
- const [regex, setRegex] = useState('');
483
- const [error, setError] = useState(null);
484
- const managedAvailable = mode.data?.managed_available === true;
485
- const useCustomKey = customKeyOpen && apiKey.trim();
486
- const canCreate = managedAvailable || Boolean(useCustomKey);
487
- const submit = () => {
488
- setError(null);
489
- if (!canCreate) {
490
- setCustomKeyOpen(true);
491
- setError('Managed Email is not configured on this deployment. Use a custom AgentMail key to continue.');
492
- return;
493
- }
494
- if (attachExisting && (!existingInboxId.trim() || !existingEmail.trim())) {
495
- setError('Existing AgentMail inbox requires both inbox ID and email address.');
496
- return;
497
- }
498
- const sender_policy = {
499
- mode: restricted ? 'restricted' : 'allow_all',
500
- allowedEmails: splitPolicyList(emails),
501
- allowedDomains: splitPolicyList(domains).map((domain) => domain.replace(/^@+/, '')),
502
- allowedRegex: regex.trim() || null,
503
- };
504
- if (sender_policy.allowedRegex) {
505
- try {
506
- new RegExp(sender_policy.allowedRegex);
507
- }
508
- catch {
509
- setError('Regex is invalid');
510
- return;
511
- }
512
- }
513
- connect.mutate({
514
- projectId,
515
- connector_slug: connectorSlug,
516
- api_key: useCustomKey ? apiKey.trim() : undefined,
517
- display_name: displayName.trim() || undefined,
518
- username: attachExisting ? undefined : username.trim() || undefined,
519
- inbox_id: attachExisting ? existingInboxId.trim() : undefined,
520
- email: attachExisting ? existingEmail.trim() : undefined,
521
- sender_policy,
522
- }, {
523
- onSuccess: onConnected,
524
- onError: (e) => setError(e.message),
525
- });
526
- };
527
- return (_jsxs("div", { className: "space-y-4", children: [_jsx(InfoBanner, { tone: managedAvailable ? 'info' : 'warning', icon: Mail, title: managedAvailable
528
- ? tI18nComplete.raw('texte654b63c8098')
529
- : tI18nComplete.raw('textafe9444782eb'), children: managedAvailable
530
- ? tI18nComplete.raw('textec9ace8d8ff6')
531
- : tI18nComplete.raw('text608977655d2d') }), _jsxs("div", { className: "grid gap-3 sm:grid-cols-2", children: [_jsx(Field, { children: _jsx(Input, { id: "email-channel-display-name", name: "email-channel-display-name", "aria-label": tI18nComplete.raw('textf912567c97f2'), value: displayName, onChange: (e) => setDisplayName(e.target.value), placeholder: tI18nComplete.raw('text952144fe1418') }) }), attachExisting ? (_jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "email-channel-existing-email", children: tI18nComplete.raw('text2fcfd290b610') }), _jsx(Input, { id: "email-channel-existing-email", name: "email-channel-existing-email", "aria-label": tI18nComplete.raw('textaa042b472947'), value: existingEmail, onChange: (e) => setExistingEmail(e.target.value.trim().toLowerCase()), placeholder: tI18nComplete.raw('textbca888f9f9fd'), autoComplete: "off", spellCheck: false })] })) : (_jsxs(Field, { children: [_jsx(Input, { id: "email-channel-username", name: "email-channel-username", "aria-label": tI18nComplete.raw('textcbf297bfb5e6'), value: username, onChange: (e) => setUsername(e.target.value.toLowerCase().replace(/[^a-z0-9._-]/g, '')), placeholder: tI18nComplete.raw('texta18603086e5b'), autoComplete: "off", spellCheck: false }), _jsxs("p", { className: "text-muted-foreground text-xs", children: [tI18nComplete.raw('textf0a216500b54'), " ", username || 'support', tI18nComplete.raw('text39e4dae21daa')] })] }))] }), _jsx("div", { className: "border-border/60 border-t pt-4", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(Checkbox, { id: "email-channel-existing-inbox", checked: attachExisting, onCheckedChange: (checked) => setAttachExisting(Boolean(checked)), className: "mt-0.5" }), _jsxs("div", { className: "min-w-0 flex-1 space-y-3", children: [_jsxs("div", { children: [_jsx(Label, { htmlFor: "email-channel-existing-inbox", children: tI18nComplete.raw('textd7cc97510eb3') }), _jsx("p", { className: "text-muted-foreground mt-1 text-xs", children: tI18nComplete.raw('text3bb2e4fa1c03') })] }), attachExisting ? (_jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "email-channel-existing-inbox-id", children: tI18nComplete.raw('texta35f4f3f0587') }), _jsx(Input, { id: "email-channel-existing-inbox-id", name: "email-channel-existing-inbox-id", "aria-label": tI18nComplete.raw('textdc5376ca47b4'), value: existingInboxId, onChange: (e) => setExistingInboxId(e.target.value.trim()), placeholder: tI18nComplete.raw('textbca888f9f9fd'), autoComplete: "off", spellCheck: false })] })) : null] })] }) }), _jsxs("div", { className: "space-y-3", children: [_jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "h-8 gap-1.5 px-0", onClick: () => setCustomKeyOpen((open) => !open), children: [_jsx(ChevronDown, { className: cn('h-3.5 w-3.5 transition-transform', customKeyOpen && 'rotate-180') }), tI18nComplete.raw('text1bb320d9db5d')] }), customKeyOpen ? (_jsxs(Field, { children: [_jsx(Input, { id: "email-channel-agentmail-api-key", name: "email-channel-agentmail-api-key", "aria-label": tI18nComplete.raw('text87b0e5101fd8'), type: "password", value: apiKey, onChange: (e) => setApiKey(e.target.value), placeholder: tI18nComplete.raw('text3ce8275b54eb'), autoComplete: "off", spellCheck: false }), _jsx("p", { className: "text-muted-foreground text-xs", children: tI18nComplete.raw('text0ec2e7ccbd17') })] })) : null] }), _jsx("div", { className: "border-border/60 bg-card rounded-md border p-4", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(Checkbox, { id: "email-channel-restrict-senders", checked: restricted, onCheckedChange: (checked) => setRestricted(Boolean(checked)), className: "mt-0.5" }), _jsxs("div", { className: "min-w-0 flex-1 space-y-3", children: [_jsxs("div", { children: [_jsx(Label, { htmlFor: "email-channel-restrict-senders", children: tI18nComplete.raw('textb1fb183269ba') }), _jsx("p", { className: "text-muted-foreground mt-1 text-xs", children: tI18nComplete.raw('text5284184cef68') })] }), restricted ? (_jsxs("div", { className: "grid gap-3 sm:grid-cols-2", children: [_jsx(Field, { children: _jsx(Input, { value: emails, onChange: (e) => setEmails(e.target.value), placeholder: tI18nComplete.raw('text542d24012988'), spellCheck: false }) }), _jsx(Field, { children: _jsx(Input, { value: domains, onChange: (e) => setDomains(e.target.value), placeholder: tI18nComplete.raw('texta379a6f6eeaf'), spellCheck: false }) }), _jsx("div", { className: "sm:col-span-2", children: _jsx(Field, { children: _jsx(Input, { value: regex, onChange: (e) => setRegex(e.target.value), placeholder: tI18nComplete.raw('text8b21058f3253'), spellCheck: false }) }) })] })) : null] })] }) }), error ? _jsx(InfoBanner, { tone: "destructive", children: error }) : null, _jsx("div", { className: "flex justify-end", children: _jsxs(Button, { size: "sm", onClick: submit, disabled: connect.isPending || mode.isLoading, children: [connect.isPending ? _jsx(Loading, { className: "mr-2 size-3.5 shrink-0" }) : null, tI18nComplete.raw('text72d9ee78a15c')] }) })] }));
532
- }
533
420
  function SlackChannelConnection({ projectId, onChanged, onRemoved, canWrite = false, }) {
534
421
  const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
535
422
  const install = useSlackInstall(projectId);
@@ -669,29 +556,6 @@ export function ConnectionSection({ projectId, connector, onChanged, canWrite =
669
556
  ? 'Connected'
670
557
  : tI18nHardcoded.raw('i18nComplete.text0303e1824670') })] })), canWrite && (_jsx(SaveBar, { dirty: dirty, saving: save.isPending, disabled: !connectionValid(draft), onSave: () => save.mutate(), onReset: reset, label: tI18nHardcoded.raw('autoComponentsProjectsCustomizeSectionsConnectorsViewJsxAttrLabelSave8c6f945f') }))] })) })] }));
671
558
  }
672
- export function AddAppPanel({ projectId, emailChannelEnabled, discoverEnabled, existingSlugs, onAdded, canWrite = false, }) {
673
- const tI18nHardcoded = useTranslations('hardcodedUi');
674
- // Self-host without Pipedream configured (KORTIX_PUBLIC_CONNECTORS_ENABLED
675
- // false) — hide Easy Connect while leaving Discover/direct sources available.
676
- const { connectorsEnabled } = useUiHostConfig();
677
- const connectStatus = useQuery({
678
- queryKey: ['connect-status'],
679
- queryFn: getConnectStatus,
680
- staleTime: 5 * 60_000,
681
- enabled: connectorsEnabled,
682
- });
683
- if (!canWrite) {
684
- return (_jsx("div", { className: "mx-auto w-full max-w-2xl space-y-8", children: _jsx(EmptyState, { icon: Plug, title: tI18nHardcoded.raw('i18nComplete.text51ae0a7e3783'), description: tI18nHardcoded.raw('i18nComplete.text0bf59aef2b27') }) }));
685
- }
686
- const easyConnectHidden = !connectorsEnabled;
687
- const easyConnectDisabled = easyConnectHidden || connectStatus.data?.configured === false;
688
- const easyConnectLabel = tI18nHardcoded.raw('autoComponentsProjectsCustomizeSectionsConnectorsViewJsxTextEasyConnect19ca1c01');
689
- const defaultTab = !easyConnectDisabled ? 'apps' : discoverEnabled ? 'discover' : 'channels';
690
- return (_jsxs("div", { className: "mx-auto w-full max-w-4xl space-y-6 p-4", children: [_jsx("header", { className: "flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between", children: _jsx("h2", { className: "text-foreground text-xl font-medium", children: tI18nHardcoded.raw('i18nComplete.text3a06bf051e48') }) }), _jsxs(Tabs, { defaultValue: defaultTab, children: [_jsxs(TabsList, { type: "underline", children: [easyConnectHidden ? null : easyConnectDisabled ? (_jsx(Hint, { label: tI18nHardcoded.raw('autoComponentsProjectsCustomizeSectionsConnectorsViewJsxTextEasyConnectc07266e0'), children: _jsx(TabsTrigger, { value: "apps", disabled: true, children: easyConnectLabel }) })) : (_jsx(TabsTrigger, { value: "apps", children: easyConnectLabel })), discoverEnabled && (_jsx(TabsTrigger, { value: "discover", children: tI18nHardcoded.raw('i18nComplete.textd4a33d5b78bc') })), _jsx(TabsTrigger, { value: "channels", children: tI18nHardcoded.raw('i18nComplete.text4c8906cf76f5') }), _jsx(TabsTrigger, { value: "custom", children: tI18nHardcoded.raw('i18nComplete.text494ca78f7374') })] }), !easyConnectDisabled && (_jsx(TabsContent, { value: "apps", className: "mt-4", children: _jsx(AppCatalogue, { projectId: projectId, existingSlugs: existingSlugs, onAdded: onAdded }) })), discoverEnabled && (_jsx(TabsContent, { value: "discover", className: "mt-4", children: _jsx(DiscoverCatalogue, { projectId: projectId, existingSlugs: existingSlugs, onAdded: onAdded }) })), _jsx(TabsContent, { value: "channels", className: "mt-4", children: _jsx(ChannelCatalogue, { projectId: projectId, emailChannelEnabled: emailChannelEnabled, onAdded: onAdded }) }), _jsx(TabsContent, { value: "custom", className: "mt-4", children: _jsx(CustomConnectorForm, { projectId: projectId, emailChannelEnabled: emailChannelEnabled, onAdded: onAdded }) })] })] }));
691
- }
692
- function ChannelCatalogue({ projectId, emailChannelEnabled, onAdded, }) {
693
- return (_jsxs("div", { className: "grid gap-3 sm:grid-cols-2", children: [emailChannelEnabled && _jsx(AddEmailConnectionCard, { projectId: projectId, onAdded: onAdded }), _jsx(AddSlackConnectionCard, { projectId: projectId, onAdded: onAdded })] }));
694
- }
695
559
  /**
696
560
  * The real Slack logo — the single Slack mark used everywhere across the
697
561
  * connectors + channels surface (catalogue cards, channel cards, connect flow),
@@ -703,97 +567,6 @@ function ChannelCatalogue({ projectId, emailChannelEnabled, onAdded, }) {
703
567
  export function SlackLogo({ className }) {
704
568
  return _jsx(Slack, { className: cn('size-4 shrink-0', className) });
705
569
  }
706
- function SlackIconTile() {
707
- return (_jsx("span", { className: "border-border/60 bg-card relative flex size-6 shrink-0 items-center justify-center overflow-hidden rounded-sm border", children: _jsx(SlackLogo, { className: "size-3.5" }) }));
708
- }
709
- const CHANNEL_CATALOGUE_CARD_CLASS = 'group bg-popover hover:bg-muted/80 focus-visible:ring-primary/50 flex flex-col rounded-md border p-3.5 text-left transition-colors focus-visible:ring-2 focus-visible:outline-none';
710
- function AddEmailConnectionCard({ projectId, onAdded, }) {
711
- const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
712
- const [open, setOpen] = useState(false);
713
- const [name, setName] = useState('Email inbox');
714
- const [username, setUsername] = useState('');
715
- const add = useMutation({
716
- mutationFn: async () => {
717
- const slug = buildEmailConnectorConnectionSlug(username || name, randomUUID());
718
- const result = await createConnector(projectId, createOnlyConnectorDraft({
719
- slug,
720
- name: name.trim() || 'Email inbox',
721
- provider: 'channel',
722
- platform: 'email',
723
- credential: 'shared',
724
- }));
725
- return { slug, syncError: connectorSyncErrorForSlug(result, slug) };
726
- },
727
- onSuccess: ({ slug, syncError }) => {
728
- setOpen(false);
729
- if (syncError) {
730
- warningToast(tI18nComplete('text4e12058e58c1', { value0: syncError }));
731
- onAdded();
732
- return;
733
- }
734
- successToast(tI18nComplete.raw('textd1dcd7a7bbec'));
735
- onAdded(slug);
736
- },
737
- onError: (err) => errorToast(err.message || tI18nComplete.raw('text3df88e8f7ea6')),
738
- });
739
- return (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", onClick: () => setOpen(true), className: CHANNEL_CATALOGUE_CARD_CLASS, children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(EntityAvatar, { icon: Mail, size: "sm" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "text-foreground truncate text-sm font-medium", children: tI18nComplete.raw('textf00606184e4d') }), _jsx("div", { className: "text-muted-foreground truncate text-xs", children: tI18nComplete.raw('text2283269ca150') })] })] }), _jsx("p", { className: "text-muted-foreground mt-2 line-clamp-2 min-h-[2rem] text-xs leading-relaxed", children: tI18nComplete.raw('text3b61c181f516') })] }), _jsx(Modal, { open: open, onOpenChange: (next) => !add.isPending && setOpen(next), children: _jsxs(ModalContent, { className: "lg:max-w-md", children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { children: tI18nComplete.raw('text2b47dcc33a2a') }), _jsx(ModalDescription, { children: tI18nComplete.raw('text630694bd2dec') })] }), _jsxs(ModalBody, { className: "max-h-[60vh] space-y-4 overflow-y-auto", children: [_jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "email-connection-name", children: tI18nComplete.raw('text2b7f6a84de91') }), _jsx(Input, { id: "email-connection-name", name: "email-connection-name", value: name, onChange: (e) => setName(e.target.value), placeholder: tI18nComplete.raw('text945ce03ec79f') })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "email-connection-prefix", children: tI18nComplete.raw('text4e6946711ca8') }), _jsx(Input, { id: "email-connection-prefix", name: "email-connection-prefix", value: username, onChange: (e) => setUsername(e.target.value.toLowerCase().replace(/[^a-z0-9._-]/g, '')), placeholder: tI18nComplete.raw('texta18603086e5b'), autoComplete: "off", spellCheck: false }), _jsx("p", { className: "text-muted-foreground text-xs", children: tI18nComplete.raw('text2549e14d07c9') })] })] }), _jsxs(ModalFooter, { className: "sm:justify-between", children: [_jsx(Button, { variant: "outline-ghost", onClick: () => setOpen(false), disabled: add.isPending, children: tI18nComplete.raw('text19766ed6ccb2') }), _jsxs(Button, { onClick: () => add.mutate(), disabled: add.isPending, className: "gap-1.5", children: [add.isPending ? _jsx(Loading, { className: "size-4 shrink-0" }) : null, tI18nComplete.raw('text8dff8c0800fd')] })] })] }) })] }));
740
- }
741
- function AddSlackConnectionCard({ projectId, onAdded, }) {
742
- const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
743
- const [open, setOpen] = useState(false);
744
- const handleConnected = () => {
745
- successToast(tI18nComplete.raw('text1bfa15228ca8'));
746
- setOpen(false);
747
- onAdded('kortix_slack');
748
- };
749
- return (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", onClick: () => setOpen(true), className: CHANNEL_CATALOGUE_CARD_CLASS, children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(SlackIconTile, {}), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "text-foreground truncate text-sm font-medium", children: tI18nComplete.raw('textb27fb38ba323') }), _jsx("div", { className: "text-muted-foreground truncate text-xs", children: tI18nComplete.raw('textbbbf43b8819c') })] })] }), _jsx("p", { className: "text-muted-foreground mt-2 line-clamp-2 min-h-[2rem] text-xs leading-relaxed", children: tI18nComplete.raw('text43b4b568012f') })] }), _jsx(Modal, { open: open, onOpenChange: setOpen, children: _jsxs(ModalContent, { className: "lg:max-w-2xl", children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { children: tI18nComplete.raw('text62da6a2b1758') }), _jsx(ModalDescription, { children: tI18nComplete.raw('text8b5b9b72f2ec') })] }), _jsx(ModalBody, { className: "max-h-[60vh] overflow-y-auto", children: _jsx(SlackConnectForm, { projectId: projectId, onConnected: handleConnected }) })] }) })] }));
750
- }
751
- /** Easy-connect app catalogue — searchable card grid with "Load more". */
752
- function AppCatalogue({ projectId, existingSlugs, onAdded, }) {
753
- const tI18nHardcoded = useTranslations('hardcodedUi');
754
- const [q, setQ] = useState('');
755
- const [selectedApp, setSelectedApp] = useState(null);
756
- const appsQuery = useInfiniteQuery({
757
- queryKey: ['easy-connect-apps', projectId, q],
758
- queryFn: ({ pageParam }) => listPipedreamApps(projectId, q || undefined, pageParam),
759
- initialPageParam: undefined,
760
- getNextPageParam: (last) => (last.hasMore ? last.nextCursor : undefined),
761
- staleTime: 60_000,
762
- });
763
- const apps = (appsQuery.data?.pages ?? []).flatMap((p) => p.apps);
764
- const visibleApps = apps.filter((app) => !BUILT_IN_CHANNEL_APP_SLUGS.has(app.slug));
765
- const notConfigured = appsQuery.isError && /501|not configured/i.test(appsQuery.error?.message ?? '');
766
- const addApp = useMutation({
767
- mutationFn: async (connector) => {
768
- if (!selectedApp)
769
- throw new Error('Select an app');
770
- const draft = buildEasyConnectConnectorDraft(selectedApp, connector);
771
- const result = await createConnector(projectId, draft);
772
- return {
773
- name: draft.name ?? selectedApp.name,
774
- slug: draft.slug,
775
- syncError: connectorSyncErrorForSlug(result, draft.slug),
776
- };
777
- },
778
- onSuccess: (connector) => {
779
- setSelectedApp(null);
780
- if (connector.syncError) {
781
- warningToast(tI18nHardcoded('i18nComplete.textd6a135de3872', {
782
- value0: connector.name,
783
- value1: connector.syncError,
784
- }));
785
- onAdded();
786
- return;
787
- }
788
- successToast(tI18nHardcoded('i18nComplete.text590d36262e11', { value0: connector.name }));
789
- onAdded(connector.slug);
790
- },
791
- onError: (err) => errorToast(err.message || tI18nHardcoded.raw('i18nComplete.texta34a2714da91')),
792
- });
793
- return (_jsxs("div", { children: [_jsxs("div", { className: "relative", children: [_jsx(Search, { className: "text-muted-foreground pointer-events-none absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2" }), _jsx(Input, { value: q, onChange: (e) => setQ(e.target.value), placeholder: tI18nHardcoded.raw('autoComponentsProjectsCustomizeSectionsConnectorsViewJsxAttrPlaceholderSearch9d26aaaa'), variant: "popover", className: "pl-9" })] }), _jsx("div", { className: "overflow-y-auto py-4", children: notConfigured ? (_jsx(InfoBanner, { tone: "neutral", title: tI18nHardcoded.raw('autoComponentsProjectsCustomizeSectionsConnectorsViewJsxAttrTitleEasy58e9c7b1'), children: tI18nHardcoded.raw('autoComponentsProjectsCustomizeSectionsConnectorsViewJsxTextEasyConnectc07266e0') })) : appsQuery.isLoading ? (_jsx("div", { className: "grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-4", children: Array.from({ length: 12 }).map((_, i) => (_jsx(Skeleton, { className: "h-[104px] w-full rounded-md" }, i))) })) : visibleApps.length === 0 ? (_jsx(EmptyState, { icon: Search, title: tI18nHardcoded.raw('autoComponentsProjectsCustomizeSectionsConnectorsViewJsxAttrTitleNof8067eda'), description: q
794
- ? tI18nHardcoded('i18nComplete.text3e71adfa7d54', { value0: q })
795
- : tI18nHardcoded.raw('i18nComplete.textecbd276ebec2') })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-4", children: visibleApps.map((app) => (_jsxs("button", { type: "button", disabled: addApp.isPending, onClick: () => setSelectedApp(app), className: "group bg-popover hover:bg-muted/80 focus-visible:ring-primary/50 flex flex-col rounded-md border p-3.5 text-left transition-colors focus-visible:ring-2 focus-visible:outline-none disabled:opacity-60", children: [_jsxs("div", { className: "flex items-center gap-3", children: [app.imgSrc ? (_jsx(Image, { src: app.imgSrc, alt: "", width: 36, height: 36, className: "size-8 shrink-0 rounded-md object-contain", referrerPolicy: "no-referrer", unoptimized: true })) : (_jsx(EntityAvatar, { icon: Zap, size: "sm" })), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "text-foreground truncate text-sm font-medium", children: app.name }), app.categories?.[0] && (_jsx("div", { className: "text-muted-foreground truncate text-xs", children: app.categories[0] }))] }), _jsx(Plus, { className: "text-muted-foreground group-hover:text-primary size-4 shrink-0 transition-colors" })] }), _jsx("p", { className: "text-muted-foreground mt-2 line-clamp-2 min-h-[2rem] text-xs leading-relaxed", children: app.description ?? ' ' })] }, app.slug))) }), appsQuery.hasNextPage && (_jsx("div", { className: "flex justify-center pt-5", children: _jsx(Button, { variant: "outline", size: "sm", onClick: () => appsQuery.fetchNextPage(), disabled: appsQuery.isFetchingNextPage, className: "h-9 px-8", children: appsQuery.isFetchingNextPage ? (_jsxs(_Fragment, { children: [_jsx(Loading, { className: "size-4 shrink-0" }), tI18nHardcoded.raw('autoComponentsProjectsCustomizeSectionsConnectorsViewJsxTextLoading7131cc18')] })) : (tI18nHardcoded.raw('i18nComplete.textac8991ef0101')) }) }))] })) }), _jsx(ConnectorConnectionModal, { open: selectedApp !== null, idPrefix: "easy-connect-connector", title: `Add ${selectedApp?.name ?? 'app'}`, description: tI18nHardcoded.raw('i18nComplete.text6acbef3d00c7'), initialName: selectedApp?.name ?? '', initialSlug: selectedApp ? proposeConnectorConnectionSlug(selectedApp.name, existingSlugs) : '', existingSlugs: existingSlugs, pending: addApp.isPending, onOpenChange: (open) => !open && setSelectedApp(null), onSubmit: (connector) => addApp.mutate(connector) })] }));
796
- }
797
570
  /**
798
571
  * Slugify the source document's own name — OpenAPI `info.title`, Postman
799
572
  * `info.name` — so adding a spec proposes the slug the API calls itself
@@ -891,9 +664,7 @@ function ConnectorConfigFields({ draft, onChange, slugEditable, emailChannelEnab
891
664
  set({
892
665
  provider,
893
666
  platform: provider === 'channel'
894
- ? draft.platform === 'email' && !emailChannelEnabled
895
- ? 'slack'
896
- : (draft.platform ?? (emailChannelEnabled ? 'email' : 'slack'))
667
+ ? (draft.platform ?? (emailChannelEnabled ? 'email' : 'slack'))
897
668
  : undefined,
898
669
  auth: provider === 'channel'
899
670
  ? { type: 'none' }
@@ -901,9 +672,7 @@ function ConnectorConfigFields({ draft, onChange, slugEditable, emailChannelEnab
901
672
  ? undefined
902
673
  : draft.auth,
903
674
  });
904
- }, children: [_jsx(SelectTrigger, { id: "connector-provider", className: "w-full", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "openapi", children: tI18nHardcoded.raw('i18nComplete.textcf2c9e218033') }), _jsx(SelectItem, { value: "postman", children: tI18nHardcoded.raw('i18nComplete.text213985e12832') }), _jsx(SelectItem, { value: "graphql", children: tI18nHardcoded.raw('i18nComplete.textee27322554e4') }), _jsx(SelectItem, { value: "mcp", children: "MCP" }), _jsx(SelectItem, { value: "http", children: "HTTP" }), _jsx(SelectItem, { value: "channel", children: tI18nHardcoded.raw('i18nComplete.textce4683e7013a') })] })] })] })] }), p === 'channel' && (_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { children: tI18nHardcoded.raw('i18nComplete.textce4683e7013a') }), _jsxs(Select, { value: draft.platform === 'email' && !emailChannelEnabled
905
- ? 'slack'
906
- : (draft.platform ?? (emailChannelEnabled ? 'email' : 'slack')), disabled: readOnly, onValueChange: (v) => set({ platform: v, auth: { type: 'none' } }), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [emailChannelEnabled && (_jsx(SelectItem, { value: "email", children: tI18nHardcoded.raw('i18nComplete.text969ccbd3cf63') })), _jsx(SelectItem, { value: "slack", children: tI18nHardcoded.raw('i18nComplete.textb27fb38ba323') })] })] })] })), (p === 'openapi' || p === 'postman') && (_jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "connector-spec", children: p === 'postman'
675
+ }, children: [_jsx(SelectTrigger, { id: "connector-provider", className: "w-full", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "openapi", children: tI18nHardcoded.raw('i18nComplete.textcf2c9e218033') }), _jsx(SelectItem, { value: "postman", children: tI18nHardcoded.raw('i18nComplete.text213985e12832') }), _jsx(SelectItem, { value: "graphql", children: tI18nHardcoded.raw('i18nComplete.textee27322554e4') }), _jsx(SelectItem, { value: "mcp", children: "MCP" }), _jsx(SelectItem, { value: "http", children: "HTTP" }), _jsx(SelectItem, { value: "channel", children: tI18nHardcoded.raw('i18nComplete.textce4683e7013a') })] })] })] })] }), p === 'channel' && (_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { children: tI18nHardcoded.raw('i18nComplete.textce4683e7013a') }), _jsxs(Select, { value: draft.platform ?? (emailChannelEnabled ? 'email' : 'slack'), disabled: readOnly, onValueChange: (v) => set({ platform: v, auth: { type: 'none' } }), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [emailChannelEnabled || draft.platform === 'email' ? (_jsx(SelectItem, { value: "email", children: tI18nHardcoded.raw('i18nComplete.text969ccbd3cf63') })) : null, _jsx(SelectItem, { value: "slack", children: tI18nHardcoded.raw('i18nComplete.textb27fb38ba323') })] })] })] })), (p === 'openapi' || p === 'postman') && (_jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "connector-spec", children: p === 'postman'
907
676
  ? tI18nHardcoded.raw('i18nComplete.textcd8dd219cc48')
908
677
  : tI18nHardcoded.raw('autoComponentsProjectsCustomizeSectionsConnectorsViewJsxAttrLabelSpec4235864d') }), _jsx(Input, { id: "connector-spec", value: draft.spec ?? '', onChange: (e) => set({ spec: e.target.value }), placeholder: p === 'postman' ? 'https://github.com/… or collection.json' : 'https://…/openapi.json', variant: "popover", disabled: readOnly, required: true }), p === 'postman' ? (_jsx(FieldDescription, { children: tI18nHardcoded.raw('i18nComplete.textc26ca4369200') })) : null] })), p === 'graphql' && (_jsxs(_Fragment, { children: [_jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "connector-endpoint", children: tI18nHardcoded.raw('i18nComplete.text3df9726c68ba') }), _jsx(Input, { id: "connector-endpoint", value: draft.endpoint ?? '', onChange: (e) => set({ endpoint: e.target.value }), placeholder: "https://api/graphql", variant: "popover", disabled: readOnly, required: true })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "connector-sdl", children: tI18nHardcoded.raw('autoComponentsProjectsCustomizeSectionsConnectorsViewJsxAttrLabelSDL2325b707') }), _jsx(Input, { id: "connector-sdl", value: draft.spec ?? '', onChange: (e) => set({ spec: e.target.value }), placeholder: tI18nHardcoded.raw('i18nComplete.textecccd43d1878'), variant: "popover", disabled: readOnly })] })] })), p === 'mcp' && (_jsxs("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: [_jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "connector-url", children: "URL" }), _jsx(Input, { id: "connector-url", value: draft.url ?? '', onChange: (e) => set({ url: e.target.value }), placeholder: "https://mcp\u2026/mcp", variant: "popover", disabled: readOnly, required: true })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "connector-transport", children: tI18nHardcoded.raw('i18nComplete.textaaead4abf5d0') }), _jsxs(Select, { value: draft.transport ?? 'http', disabled: readOnly, onValueChange: (v) => set({ transport: v }), children: [_jsx(SelectTrigger, { id: "connector-transport", className: "w-full", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "http", children: tI18nHardcoded.raw('i18nComplete.texte0603c499aae') }), _jsx(SelectItem, { value: "sse", children: tI18nHardcoded.raw('i18nComplete.textfe3811fe21af') })] })] })] })] })), p === 'http' && (_jsxs(_Fragment, { children: [_jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "connector-base-url", children: tI18nHardcoded.raw('autoComponentsProjectsCustomizeSectionsConnectorsViewJsxAttrLabelBase744ecef9') }), _jsx(Input, { id: "connector-base-url", value: draft.baseUrl ?? '', onChange: (e) => set({ baseUrl: e.target.value }), placeholder: "https://api.internal", variant: "popover", disabled: readOnly, required: true })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "connector-routes", children: tI18nHardcoded.raw('autoComponentsProjectsCustomizeSectionsConnectorsViewJsxAttrLabelRoutes38b14436') }), _jsx(Input, { id: "connector-routes", value: draft.spec ?? '', onChange: (e) => set({ spec: e.target.value }), placeholder: tI18nHardcoded.raw('i18nComplete.textb2c293b68745'), variant: "popover", disabled: readOnly })] })] })), needsAuth && (_jsxs("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: [_jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "connector-auth", children: tI18nHardcoded.raw('i18nComplete.text8eb3ea9bbde6') }), _jsxs(Select, { value: oauth2Selected ? 'oauth2_client_credentials' : (draft.auth?.type ?? 'auto'), disabled: readOnly, onValueChange: (v) => {
909
678
  if (v === 'oauth2_client_credentials') {
@@ -937,8 +706,9 @@ function connectionValid(d, emailChannelEnabled = true) {
937
706
  }
938
707
  return true;
939
708
  }
940
- export function CustomConnectorForm({ projectId, emailChannelEnabled, onAdded, }) {
709
+ export function CustomConnectorForm({ projectId, onAdded, }) {
941
710
  const tI18nHardcoded = useTranslations('hardcodedUi');
711
+ const emailChannelEnabled = useFeatureFlag(projectId, 'email_channel').enabled;
942
712
  const [draft, setDraft] = useState({
943
713
  slug: '',
944
714
  provider: 'openapi',
@@ -950,9 +720,6 @@ export function CustomConnectorForm({ projectId, emailChannelEnabled, onAdded, }
950
720
  const timer = window.setTimeout(() => setDiscoveryDraft(draft), 400);
951
721
  return () => window.clearTimeout(timer);
952
722
  }, [draft]);
953
- if (!emailChannelEnabled && draft.provider === 'channel' && draft.platform === 'email') {
954
- setDraft((current) => ({ ...current, platform: 'slack' }));
955
- }
956
723
  // Channel connectors have no OAuth2-at-creation offer.
957
724
  if (draft.provider === 'channel' && oauth2Selected) {
958
725
  setOauth2Selected(false);