@kortix/ui 0.14.7 → 0.14.9

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 (576) hide show
  1. package/README.md +2 -2
  2. package/dist/_vendor/kortix-shared.js +64 -4
  3. package/dist/_vendor/shared/app-config.d.ts +175 -0
  4. package/dist/_vendor/shared/channel-message.d.ts +34 -5
  5. package/dist/_vendor/shared/index.d.ts +1 -0
  6. package/dist/_vendor/shared/runtime-versions.d.ts +4 -0
  7. package/dist/_vendor/shared/space-slug.d.ts +37 -0
  8. package/dist/access/access/access-detail-shell.js +1 -1
  9. package/dist/access/access/access-dialog-share.js +4 -7
  10. package/dist/access/access/access-dialog.js +2 -1
  11. package/dist/access/access/principal-picker.d.ts +11 -0
  12. package/dist/access/access/principal-picker.js +9 -7
  13. package/dist/apps/app-preview-pool.d.ts +7 -2
  14. package/dist/apps/app-preview-pool.js +11 -5
  15. package/dist/apps/app-shared.d.ts +22 -15
  16. package/dist/apps/app-shared.js +37 -19
  17. package/dist/apps/index.d.ts +2 -2
  18. package/dist/apps/index.js +2 -2
  19. package/dist/artifacts/artifact-frame.d.ts +16 -0
  20. package/dist/artifacts/artifact-frame.js +51 -0
  21. package/dist/artifacts/artifact-session.d.ts +18 -0
  22. package/dist/artifacts/artifact-session.js +101 -0
  23. package/dist/artifacts/frame-policy.d.ts +30 -0
  24. package/dist/artifacts/frame-policy.js +61 -0
  25. package/dist/artifacts/index.d.ts +3 -0
  26. package/dist/artifacts/index.js +5 -0
  27. package/dist/browser/sandbox-browser-chrome.d.ts +4 -1
  28. package/dist/browser/sandbox-browser-chrome.js +2 -2
  29. package/dist/customize/agents/agent-cover-card.d.ts +17 -0
  30. package/dist/customize/agents/agent-cover-card.js +13 -0
  31. package/dist/customize/agents/agent-grant-pages.d.ts +5 -1
  32. package/dist/customize/agents/agent-grant-pages.js +30 -4
  33. package/dist/customize/agents/agent-page.js +8 -33
  34. package/dist/customize/agents/agent-policy-sets.d.ts +43 -0
  35. package/dist/customize/agents/agent-policy-sets.js +72 -0
  36. package/dist/customize/agents/agent-triggers-section.js +2 -1
  37. package/dist/customize/agents/agents-page.js +43 -49
  38. package/dist/customize/connectors/add-mcp/add-mcp-server-dialog.d.ts +6 -1
  39. package/dist/customize/connectors/add-mcp/add-mcp-server-dialog.js +10 -4
  40. package/dist/customize/connectors/agent-access.d.ts +35 -0
  41. package/dist/customize/connectors/agent-access.js +77 -0
  42. package/dist/customize/connectors/catalog/browse-sections.d.ts +2 -29
  43. package/dist/customize/connectors/catalog/browse-sections.js +7 -74
  44. package/dist/customize/connectors/catalog/catalog-entry.d.ts +18 -37
  45. package/dist/customize/connectors/catalog/catalog-entry.js +28 -40
  46. package/dist/customize/connectors/catalog/connector-browse.d.ts +3 -32
  47. package/dist/customize/connectors/catalog/connector-browse.js +19 -50
  48. package/dist/customize/connectors/catalog/use-catalog.d.ts +20 -59
  49. package/dist/customize/connectors/catalog/use-catalog.js +48 -175
  50. package/dist/customize/connectors/connector-identity.d.ts +9 -11
  51. package/dist/customize/connectors/connector-identity.js +13 -42
  52. package/dist/customize/connectors/connector-moves-banner.d.ts +2 -1
  53. package/dist/customize/connectors/connector-moves-banner.js +4 -6
  54. package/dist/customize/connectors/connector-routes.d.ts +21 -9
  55. package/dist/customize/connectors/connector-routes.js +29 -20
  56. package/dist/customize/connectors/connectors-page.js +53 -82
  57. package/dist/customize/connectors/detail/app-page.js +226 -98
  58. package/dist/customize/connectors/detail/computer-app-page.d.ts +16 -0
  59. package/dist/customize/connectors/detail/computer-app-page.js +39 -0
  60. package/dist/customize/connectors/detail/connector-accounts.js +3 -1
  61. package/dist/customize/connectors/detail/connector-advanced-tools.d.ts +4 -1
  62. package/dist/customize/connectors/detail/connector-advanced-tools.js +2 -2
  63. package/dist/customize/connectors/detail/connector-agents.d.ts +14 -0
  64. package/dist/customize/connectors/detail/connector-agents.js +69 -0
  65. package/dist/customize/connectors/detail/connector-detail-tabs.js +2 -1
  66. package/dist/customize/connectors/detail/connector-move-row.d.ts +8 -5
  67. package/dist/customize/connectors/detail/connector-move-row.js +23 -14
  68. package/dist/customize/connectors/detail/connector-page.d.ts +4 -1
  69. package/dist/customize/connectors/detail/connector-page.js +14 -10
  70. package/dist/customize/connectors/detail/connector-policy-sets.d.ts +28 -0
  71. package/dist/customize/connectors/detail/connector-policy-sets.js +203 -0
  72. package/dist/customize/connectors/detail/connector-settings.d.ts +4 -1
  73. package/dist/customize/connectors/detail/connector-settings.js +7 -3
  74. package/dist/customize/connectors/detail/connector-status.d.ts +19 -6
  75. package/dist/customize/connectors/detail/connector-status.js +34 -10
  76. package/dist/customize/connectors/detail/connector-tabs.d.ts +4 -1
  77. package/dist/customize/connectors/detail/connector-tabs.js +8 -2
  78. package/dist/customize/connectors/detail/connector-tools.d.ts +3 -3
  79. package/dist/customize/connectors/detail/connector-tools.js +105 -48
  80. package/dist/customize/connectors/detail/email-inboxes.d.ts +43 -0
  81. package/dist/customize/connectors/detail/email-inboxes.js +184 -0
  82. package/dist/customize/connectors/detail/provider-info.d.ts +1 -1
  83. package/dist/customize/connectors/detail/provider-info.js +2 -2
  84. package/dist/customize/connectors/detail/status-badge.d.ts +1 -1
  85. package/dist/customize/connectors/detail/status-badge.js +4 -5
  86. package/dist/customize/connectors/detail/use-connector-detail.d.ts +6 -0
  87. package/dist/customize/connectors/detail/use-connector-detail.js +14 -4
  88. package/dist/customize/connectors/install/install-dialog.d.ts +23 -0
  89. package/dist/customize/connectors/install/install-dialog.js +40 -0
  90. package/dist/customize/connectors/install/install.d.ts +13 -2
  91. package/dist/customize/connectors/install/install.js +9 -4
  92. package/dist/customize/connectors/install/use-install.d.ts +19 -2
  93. package/dist/customize/connectors/install/use-install.js +65 -37
  94. package/dist/customize/connectors/install/way-kind.d.ts +5 -0
  95. package/dist/customize/connectors/install/way-kind.js +16 -0
  96. package/dist/customize/connectors/provider-label.d.ts +2 -1
  97. package/dist/customize/connectors/provider-label.js +13 -3
  98. package/dist/customize/connectors/tools/pattern-rule-draft.d.ts +4 -0
  99. package/dist/customize/connectors/tools/pattern-rule-draft.js +12 -3
  100. package/dist/customize/connectors/tools/policy-sets.d.ts +27 -0
  101. package/dist/customize/connectors/tools/policy-sets.js +41 -0
  102. package/dist/customize/connectors/tools/tool-groups.d.ts +32 -9
  103. package/dist/customize/connectors/tools/tool-groups.js +78 -16
  104. package/dist/customize/connectors/tools/tool-policy-control.d.ts +11 -10
  105. package/dist/customize/connectors/tools/tool-policy-control.js +15 -16
  106. package/dist/customize/connectors/tools/tool-policy-labels.d.ts +6 -5
  107. package/dist/customize/connectors/tools/tool-policy-labels.js +17 -16
  108. package/dist/customize/connectors/tools/tool-policy.d.ts +50 -4
  109. package/dist/customize/connectors/tools/tool-policy.js +74 -8
  110. package/dist/customize/connectors/use-agent-access.d.ts +85 -0
  111. package/dist/customize/connectors/use-agent-access.js +72 -0
  112. package/dist/customize/migrate-to-v2/index.d.ts +1 -2
  113. package/dist/customize/migrate-to-v2/index.js +1 -2
  114. package/dist/customize/migrate-to-v2/migration-prompt.d.ts +12 -24
  115. package/dist/customize/migrate-to-v2/migration-prompt.js +34 -235
  116. package/dist/customize/migrate-to-v2/upgrade-defs.d.ts +1 -1
  117. package/dist/customize/migrate-to-v2/upgrade-defs.js +7 -6
  118. package/dist/customize/migrate-to-v2/upgrade-view.js +7 -7
  119. package/dist/customize/migrate-to-v2/use-run-upgrade.d.ts +3 -3
  120. package/dist/customize/providers/provider-accordion.js +17 -2
  121. package/dist/customize/sections/component/channel-access-panel.d.ts +16 -0
  122. package/dist/customize/sections/component/channel-access-panel.js +146 -0
  123. package/dist/customize/sections/component/channel-connect-hero.d.ts +3 -2
  124. package/dist/customize/sections/component/channel-connect-hero.js +3 -2
  125. package/dist/customize/sections/component/channel-hero-frame.d.ts +31 -0
  126. package/dist/customize/sections/component/channel-hero-frame.js +40 -0
  127. package/dist/customize/sections/component/channel-mocks.d.ts +6 -0
  128. package/dist/customize/sections/component/channel-mocks.js +46 -0
  129. package/dist/customize/sections/component/channel-row.d.ts +13 -3
  130. package/dist/customize/sections/component/channel-row.js +10 -4
  131. package/dist/customize/sections/component/email-connect-form.d.ts +27 -0
  132. package/dist/customize/sections/component/email-connect-form.js +183 -0
  133. package/dist/customize/sections/component/slack-connect-card.d.ts +7 -0
  134. package/dist/customize/sections/component/slack-connect-card.js +2 -3
  135. package/dist/customize/sections/component/teams-connect-card.d.ts +7 -0
  136. package/dist/customize/sections/component/teams-connect-card.js +2 -3
  137. package/dist/customize/sections/component/telegram-channel-row.js +16 -25
  138. package/dist/customize/sections/connectors-view.d.ts +1 -15
  139. package/dist/customize/sections/connectors-view.js +81 -314
  140. package/dist/customize/sections/view/agent-editor-catalog.js +5 -0
  141. package/dist/customize/sections/view/channels-view.d.ts +5 -1
  142. package/dist/customize/sections/view/channels-view.js +63 -81
  143. package/dist/customize/sections/view/gateway/gateway-overview.js +10 -2
  144. package/dist/customize/settings/tabs/experimental-tab.js +35 -16
  145. package/dist/customize/shared/catalog/catalog-empty-state.d.ts +1 -12
  146. package/dist/customize/shared/catalog/catalog-empty-state.js +3 -3
  147. package/dist/customize/shared/channels-switch-dialog.d.ts +18 -0
  148. package/dist/customize/shared/channels-switch-dialog.js +30 -0
  149. package/dist/customize/shared/feature-gate-screen.js +27 -9
  150. package/dist/customize/shared/new-entity-menu.js +4 -1
  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/skills/skills-page.js +4 -5
  154. package/dist/customize/triggers/schedule/post-to-field.d.ts +18 -0
  155. package/dist/customize/triggers/schedule/post-to-field.js +49 -0
  156. package/dist/customize/triggers/schedule/schedule-copy.d.ts +10 -6
  157. package/dist/customize/triggers/schedule/schedule-copy.js +42 -11
  158. package/dist/customize/triggers/schedule/schedule-detail-sheet.js +2 -1
  159. package/dist/customize/triggers/schedule/then-fields.js +1 -5
  160. package/dist/customize/triggers/schedule/trigger-composer-logic.d.ts +22 -0
  161. package/dist/customize/triggers/schedule/trigger-composer-logic.js +25 -0
  162. package/dist/customize/triggers/schedule/trigger-composer.d.ts +5 -0
  163. package/dist/customize/triggers/schedule/trigger-composer.js +23 -14
  164. package/dist/customize/triggers/schedule/trigger-edit-logic.js +3 -0
  165. package/dist/customize/triggers/schedule/trigger-filter.js +1 -1
  166. package/dist/customize/triggers/schedule/trigger-runs-logic.d.ts +2 -2
  167. package/dist/customize/triggers/schedule/trigger-runs-panel.js +1 -0
  168. package/dist/customize/triggers/schedule/trigger-toast.js +2 -1
  169. package/dist/customize/triggers/schedule-view.js +9 -4
  170. package/dist/files/index.d.ts +1 -0
  171. package/dist/files/index.js +1 -0
  172. package/dist/files/project/change-request-recovery.d.ts +1 -26
  173. package/dist/files/project/change-request-recovery.js +1 -59
  174. package/dist/files/project/components/change-request-detail-dialog.js +13 -3
  175. package/dist/files/project/components/drive-explorer.js +15 -15
  176. package/dist/files/project/components/drive-toolbar.d.ts +16 -2
  177. package/dist/files/project/components/drive-toolbar.js +14 -5
  178. package/dist/files/project/hooks/use-change-request-recovery.js +3 -19
  179. package/dist/files/project/hooks/use-change-requests.d.ts +1 -0
  180. package/dist/files/project/hooks/use-change-requests.js +11 -2
  181. package/dist/files/renderers/image-frame.d.ts +46 -0
  182. package/dist/files/renderers/image-frame.js +59 -0
  183. package/dist/files/renderers/image-renderer.d.ts +11 -1
  184. package/dist/files/renderers/image-renderer.js +13 -3
  185. package/dist/files/renderers/pdf/pdf-clipboard.d.ts +2 -0
  186. package/dist/files/renderers/pdf/pdf-clipboard.js +21 -0
  187. package/dist/files/renderers/pdf/pdf-viewer.js +4 -2
  188. package/dist/files/renderers/show-content-renderer.d.ts +9 -1
  189. package/dist/files/renderers/show-content-renderer.js +56 -14
  190. package/dist/files/runtime/file-source.js +2 -0
  191. package/dist/files/runtime/hooks/use-binary-blob.d.ts +10 -1
  192. package/dist/files/runtime/hooks/use-binary-blob.js +10 -4
  193. package/dist/files/runtime/hooks/use-shared-image.d.ts +41 -0
  194. package/dist/files/runtime/hooks/use-shared-image.js +177 -0
  195. package/dist/files/viewer/file-content-renderer.d.ts +22 -1
  196. package/dist/files/viewer/file-content-renderer.js +50 -7
  197. package/dist/files/viewer/file-header.d.ts +7 -3
  198. package/dist/files/viewer/file-header.js +20 -11
  199. package/dist/files/viewer/file-preview-modal.d.ts +1 -1
  200. package/dist/files/viewer/file-preview-modal.js +10 -22
  201. package/dist/files/viewer/file-source.d.ts +13 -0
  202. package/dist/files/viewer/use-file-content-state.d.ts +2 -0
  203. package/dist/files/viewer/use-file-content-state.js +28 -10
  204. package/dist/files/viewer/viewer-actions.d.ts +3 -1
  205. package/dist/files/viewer/viewer-actions.js +2 -2
  206. package/dist/hooks/use-media-query.d.ts +1 -0
  207. package/dist/hooks/use-mobile.d.ts +5 -0
  208. package/dist/hooks/use-mobile.js +8 -0
  209. package/dist/i18n/en.d.ts +906 -70
  210. package/dist/i18n/en.js +924 -88
  211. package/dist/i18n/ui-catalog/localize-ui-catalog.js +4 -0
  212. package/dist/i18n/ui-catalog/remaining-ui-translation-keys.generated.js +15 -3
  213. package/dist/index.d.ts +2 -2
  214. package/dist/index.js +2 -2
  215. package/dist/internal/account-hub/account-settings-sidebar.js +1 -1
  216. package/dist/internal/account-hub/hub-sheet.d.ts +9 -1
  217. package/dist/internal/account-hub/hub-sheet.js +21 -5
  218. package/dist/internal/account-hub/sections.d.ts +1 -1
  219. package/dist/internal/account-hub/sections.js +2 -1
  220. package/dist/internal/auth/auth-card-shell.js +3 -3
  221. package/dist/internal/components/agent-mark.d.ts +38 -0
  222. package/dist/internal/components/agent-mark.js +41 -0
  223. package/dist/internal/connector-logo/connector-logo-source.d.ts +63 -0
  224. package/dist/internal/connector-logo/connector-logo-source.js +48 -0
  225. package/dist/internal/connector-logo/connector-logo.d.ts +39 -0
  226. package/dist/internal/connector-logo/connector-logo.js +56 -0
  227. package/dist/internal/connector-logo/connector-mark-files.d.ts +11 -0
  228. package/dist/internal/connector-logo/connector-mark-files.js +35 -0
  229. package/dist/internal/files/file-read-retry.d.ts +13 -0
  230. package/dist/internal/files/file-read-retry.js +23 -3
  231. package/dist/internal/files/session-drive-files.d.ts +5 -1
  232. package/dist/internal/files/session-drive-files.js +7 -2
  233. package/dist/internal/hooks/channels/use-channels-installations.d.ts +32 -5
  234. package/dist/internal/hooks/channels/use-channels-installations.js +55 -7
  235. package/dist/internal/hooks/channels/use-email-inboxes.d.ts +19 -0
  236. package/dist/internal/hooks/channels/use-email-inboxes.js +48 -0
  237. package/dist/internal/hooks/connectors/use-add-account.js +1 -1
  238. package/dist/internal/hooks/index.d.ts +1 -1
  239. package/dist/internal/hooks/index.js +1 -1
  240. package/dist/internal/hooks/projects/use-new-project-session.d.ts +9 -0
  241. package/dist/internal/hooks/projects/use-new-project-session.js +28 -12
  242. package/dist/internal/hooks/use-auto-scroll.d.ts +8 -1
  243. package/dist/internal/hooks/use-auto-scroll.js +4 -4
  244. package/dist/internal/icons/telegram.d.ts +5 -0
  245. package/dist/internal/icons/telegram.js +6 -1
  246. package/dist/internal/layout/nav-hover-card.d.ts +35 -0
  247. package/dist/internal/layout/nav-hover-card.js +84 -0
  248. package/dist/internal/layout/project-nav-row.d.ts +3 -1
  249. package/dist/internal/layout/project-nav-row.js +3 -2
  250. package/dist/internal/layout/project-page-header.d.ts +4 -2
  251. package/dist/internal/layout/project-page-header.js +4 -3
  252. package/dist/internal/layout/project-settings-nav.js +59 -2
  253. package/dist/internal/lib/browser-error-noise.d.ts +1 -1
  254. package/dist/internal/lib/browser-error-noise.js +1 -1
  255. package/dist/internal/lib/browser-noise/rules/injected-scripts.d.ts +7 -0
  256. package/dist/internal/lib/browser-noise/rules/injected-scripts.js +15 -0
  257. package/dist/internal/lib/manifest-version.d.ts +1 -1
  258. package/dist/internal/lib/manifest-version.js +2 -2
  259. package/dist/internal/lib/memory-href.d.ts +16 -0
  260. package/dist/internal/lib/memory-href.js +46 -0
  261. package/dist/internal/lib/pixel-mark.d.ts +33 -0
  262. package/dist/internal/lib/pixel-mark.js +152 -0
  263. package/dist/internal/lib/use-project-feature-flags.js +11 -11
  264. package/dist/internal/lib/utils/heic-convert.d.ts +1 -1
  265. package/dist/internal/lib/utils/heic-convert.js +3 -4
  266. package/dist/internal/lib/web-notifications.d.ts +20 -0
  267. package/dist/internal/lib/web-notifications.js +48 -4
  268. package/dist/internal/notifications/notification-bell.d.ts +4 -1
  269. package/dist/internal/notifications/notification-bell.js +2 -2
  270. package/dist/internal/selection/selection-bar.d.ts +2 -1
  271. package/dist/internal/selection/selection-bar.js +1 -1
  272. package/dist/internal/stores/file-preview-store.d.ts +29 -2
  273. package/dist/internal/stores/file-preview-store.js +19 -1
  274. package/dist/internal/stores/kortix-computer-store.js +3 -0
  275. package/dist/internal/stores/sidebar-nav-store.d.ts +1 -1
  276. package/dist/internal/stores/sidebar-nav-store.js +3 -1
  277. package/dist/lib/routes.d.ts +13 -1
  278. package/dist/lib/routes.js +13 -0
  279. package/dist/markdown/genui/components/inline.d.ts +1 -1
  280. package/dist/markdown/index.d.ts +2 -1
  281. package/dist/markdown/index.js +2 -1
  282. package/dist/markdown/setup-links/approval-decision.d.ts +1 -0
  283. package/dist/markdown/setup-links/approval-decision.js +6 -2
  284. package/dist/markdown/setup-links/connector-handshake.d.ts +3 -1
  285. package/dist/markdown/setup-links/connector-handshake.js +12 -10
  286. package/dist/markdown/setup-links/show-connect-hero.d.ts +28 -0
  287. package/dist/markdown/setup-links/show-connect-hero.js +91 -0
  288. package/dist/markdown/unified-markdown.js +5 -5
  289. package/dist/primitives/badge.d.ts +1 -1
  290. package/dist/primitives/badge.js +2 -0
  291. package/dist/primitives/disclosure.js +14 -2
  292. package/dist/primitives/empty-art.d.ts +12 -0
  293. package/dist/primitives/empty-art.js +11 -0
  294. package/dist/primitives/entity-avatar.d.ts +4 -1
  295. package/dist/primitives/entity-avatar.js +4 -2
  296. package/dist/primitives/mermaid-renderer.d.ts +2 -0
  297. package/dist/primitives/mermaid-renderer.js +21 -15
  298. package/dist/primitives/resizable.js +6 -1
  299. package/dist/primitives/resize-seam.d.ts +11 -0
  300. package/dist/primitives/resize-seam.js +12 -0
  301. package/dist/primitives/sidebar-panel.js +4 -7
  302. package/dist/primitives/tabs.d.ts +14 -1
  303. package/dist/primitives/tabs.js +1 -1
  304. package/dist/primitives/user-avatar.d.ts +3 -1
  305. package/dist/primitives/user-avatar.js +4 -2
  306. package/dist/providers/ui-provider.d.ts +10 -1
  307. package/dist/session/composer/ComposerAboveCard.d.ts +1 -1
  308. package/dist/session/composer/ComposerAboveCard.js +2 -2
  309. package/dist/session/composer/ComposerCard.d.ts +1 -1
  310. package/dist/session/composer/ComposerCard.js +3 -3
  311. package/dist/session/composer/agent-selector.d.ts +19 -1
  312. package/dist/session/composer/agent-selector.js +42 -12
  313. package/dist/session/composer/composer-agent-access.d.ts +15 -0
  314. package/dist/session/composer/composer-agent-access.js +27 -0
  315. package/dist/session/composer/composer-chat-input.d.ts +8 -2
  316. package/dist/session/composer/composer-chat-input.js +8 -6
  317. package/dist/session/composer/composer-logic.d.ts +16 -0
  318. package/dist/session/composer/composer-logic.js +12 -0
  319. package/dist/session/composer/composer-underbar.d.ts +3 -1
  320. package/dist/session/composer/composer-underbar.js +4 -3
  321. package/dist/session/composer/composer.d.ts +15 -1
  322. package/dist/session/composer/composer.js +19 -1
  323. package/dist/session/composer/context-usage.d.ts +5 -0
  324. package/dist/session/composer/context-usage.js +6 -1
  325. package/dist/session/composer/draft/composer-draft.d.ts +6 -2
  326. package/dist/session/composer/draft/composer-draft.js +5 -1
  327. package/dist/session/composer/reasoning-effort-selector.js +1 -1
  328. package/dist/session/composer/token-progress.js +4 -4
  329. package/dist/session/header/export-transcript-modal.d.ts +3 -2
  330. package/dist/session/header/export-transcript-modal.js +6 -3
  331. package/dist/session/models/chatgpt-connection-button.d.ts +11 -0
  332. package/dist/session/models/chatgpt-connection-button.js +54 -0
  333. package/dist/session/models/model-selector.d.ts +3 -1
  334. package/dist/session/models/model-selector.js +7 -3
  335. package/dist/session/models/use-model-connection-gate.d.ts +5 -5
  336. package/dist/session/models/use-model-connection-gate.js +5 -5
  337. package/dist/session/outcomes/jump-to-outcome.d.ts +10 -0
  338. package/dist/session/outcomes/jump-to-outcome.js +11 -0
  339. package/dist/session/outcomes/session-outcomes-bridge.d.ts +14 -0
  340. package/dist/session/outcomes/session-outcomes-bridge.js +12 -0
  341. package/dist/session/outcomes/session-outcomes-provider.d.ts +3 -1
  342. package/dist/session/outcomes/session-outcomes-provider.js +33 -3
  343. package/dist/session/panel/easy/app-preview.d.ts +10 -0
  344. package/dist/session/panel/easy/app-preview.js +31 -12
  345. package/dist/session/panel/easy/change-requests-card.d.ts +7 -0
  346. package/dist/session/panel/easy/change-requests-card.js +17 -0
  347. package/dist/session/panel/easy/easy-panel-logic.js +7 -1
  348. package/dist/session/panel/easy/easy-panel.js +5 -2
  349. package/dist/session/panel/easy/file-preview.js +1 -1
  350. package/dist/session/panel/easy/outputs-card.d.ts +2 -1
  351. package/dist/session/panel/easy/outputs-card.js +3 -2
  352. package/dist/session/panel/easy/plan-card.d.ts +2 -0
  353. package/dist/session/panel/easy/plan-card.js +2 -0
  354. package/dist/session/panel/mobile-tool-drawer.js +7 -1
  355. package/dist/session/panel/session-audit-panel.js +9 -2
  356. package/dist/session/panel/session-detail-panel.js +9 -3
  357. package/dist/session/panel/session-files-explorer.d.ts +9 -0
  358. package/dist/session/panel/session-files-explorer.js +12 -3
  359. package/dist/session/panel/session-panel-provider.d.ts +15 -1
  360. package/dist/session/panel/session-panel-provider.js +32 -7
  361. package/dist/session/panel/shared/derive-panels.d.ts +8 -1
  362. package/dist/session/panel/shared/derive-panels.js +12 -2
  363. package/dist/session/panel/shared/output-priority.js +2 -0
  364. package/dist/session/participants/session-participants.d.ts +5 -1
  365. package/dist/session/participants/session-participants.js +9 -2
  366. package/dist/session/prompts/approval-request.d.ts +5 -0
  367. package/dist/session/prompts/approval-request.js +7 -1
  368. package/dist/session/prompts/session-approval-review.d.ts +9 -0
  369. package/dist/session/prompts/session-approval-review.js +18 -0
  370. package/dist/session/status/session-error-banner.js +2 -49
  371. package/dist/session/status/session-starting-loader.d.ts +14 -2
  372. package/dist/session/status/session-starting-loader.js +16 -4
  373. package/dist/session/thread/after-first-prompt.d.ts +7 -0
  374. package/dist/session/thread/after-first-prompt.js +8 -0
  375. package/dist/session/thread/detect-command.d.ts +12 -0
  376. package/dist/session/thread/detect-command.js +20 -0
  377. package/dist/session/thread/plan-surface.d.ts +1 -0
  378. package/dist/session/thread/plan-surface.js +1 -0
  379. package/dist/session/thread/session-chat.d.ts +3 -1
  380. package/dist/session/thread/session-chat.js +377 -252
  381. package/dist/session/thread/session-context-metrics.d.ts +15 -0
  382. package/dist/session/thread/session-context-metrics.js +10 -1
  383. package/dist/session/thread/session-context-modal.d.ts +4 -2
  384. package/dist/session/thread/session-context-modal.js +16 -9
  385. package/dist/session/thread/session-thread.d.ts +3 -1
  386. package/dist/session/thread/session-thread.js +9 -2
  387. package/dist/session/thread/thread-boot-rows.d.ts +36 -0
  388. package/dist/session/thread/thread-boot-rows.js +89 -0
  389. package/dist/session/thread/transcript-rows.d.ts +31 -0
  390. package/dist/session/thread/transcript-rows.js +3 -0
  391. package/dist/session/thread/transcript.d.ts +4 -9
  392. package/dist/session/thread/transcript.js +119 -21
  393. package/dist/session/thread/turn-share.d.ts +16 -0
  394. package/dist/session/thread/turn-share.js +162 -0
  395. package/dist/session/tool/shared/infrastructure-contexts.d.ts +28 -0
  396. package/dist/session/tool/shared/infrastructure-contexts.js +31 -3
  397. package/dist/session/tool/tool-part-renderer.d.ts +5 -4
  398. package/dist/session/tool/tool-part-renderer.js +8 -3
  399. package/dist/session/tool/tools/apply-patch-tool.d.ts +1 -0
  400. package/dist/session/tool/tools/apply-patch-tool.js +1 -0
  401. package/dist/session/tool/tools/bash-tool.js +7 -6
  402. package/dist/session/tool/tools/channel-send-card.d.ts +1 -2
  403. package/dist/session/tool/tools/channel-send.d.ts +2 -1
  404. package/dist/session/tool/tools/codemode-tool.js +1 -1
  405. package/dist/session/tool/tools/connector-tools.js +1 -1
  406. package/dist/session/tool/tools/image-gen-tool.d.ts +1 -1
  407. package/dist/session/tool/tools/image-gen-tool.js +240 -53
  408. package/dist/session/tool/tools/pty-kill-tool.d.ts +1 -0
  409. package/dist/session/tool/tools/pty-kill-tool.js +1 -0
  410. package/dist/session/tool/tools/pty-read-tool.d.ts +2 -0
  411. package/dist/session/tool/tools/pty-read-tool.js +2 -0
  412. package/dist/session/tool/tools/pty-spawn-tool.d.ts +1 -0
  413. package/dist/session/tool/tools/pty-spawn-tool.js +1 -0
  414. package/dist/session/tool/tools/pty-write-tool.d.ts +1 -0
  415. package/dist/session/tool/tools/pty-write-tool.js +1 -0
  416. package/dist/session/tool/tools/show-tool.js +19 -8
  417. package/dist/session/tool/tools/todo-write-tool.d.ts +1 -0
  418. package/dist/session/tool/tools/todo-write-tool.js +1 -0
  419. package/dist/session/turn/channel-brand.d.ts +8 -3
  420. package/dist/session/turn/channel-brand.js +20 -4
  421. package/dist/session/turn/message-author-label.js +6 -2
  422. package/dist/session/turn/message-author.d.ts +8 -0
  423. package/dist/session/turn/message-author.js +24 -0
  424. package/dist/session/turn/message-row.d.ts +52 -0
  425. package/dist/session/turn/message-row.js +44 -0
  426. package/dist/session/turn/plan-anchor.d.ts +4 -1
  427. package/dist/session/turn/plan-anchor.js +4 -1
  428. package/dist/session/turn/plan-card.d.ts +7 -0
  429. package/dist/session/turn/plan-card.js +7 -0
  430. package/dist/session/turn/user-message.d.ts +7 -1
  431. package/dist/session/turn/user-message.js +21 -7
  432. package/dist/styles.css +1 -1
  433. package/dist/terminal/session-terminal-connect-bar.js +2 -1
  434. package/dist/workspace/home/access-requests-bell.d.ts +9 -2
  435. package/dist/workspace/home/access-requests-bell.js +20 -6
  436. package/dist/workspace/home/first-chat.d.ts +8 -21
  437. package/dist/workspace/home/first-chat.js +22 -72
  438. package/dist/workspace/index.d.ts +6 -0
  439. package/dist/workspace/index.js +6 -0
  440. package/dist/workspace/layout/project-home.d.ts +14 -2
  441. package/dist/workspace/layout/project-home.js +60 -21
  442. package/dist/workspace/layout/use-project-home-send.d.ts +9 -1
  443. package/dist/workspace/layout/use-project-home-send.js +82 -3
  444. package/dist/workspace/memory/body-doc.d.ts +17 -0
  445. package/dist/workspace/memory/body-doc.js +208 -0
  446. package/dist/workspace/memory/body-extensions.d.ts +38 -0
  447. package/dist/workspace/memory/body-extensions.js +103 -0
  448. package/dist/workspace/memory/company-memory-page.d.ts +8 -0
  449. package/dist/workspace/memory/company-memory-page.js +16 -0
  450. package/dist/workspace/memory/memory-all.d.ts +20 -0
  451. package/dist/workspace/memory/memory-all.js +27 -0
  452. package/dist/workspace/memory/memory-body.d.ts +19 -0
  453. package/dist/workspace/memory/memory-body.js +139 -0
  454. package/dist/workspace/memory/memory-empty.d.ts +13 -0
  455. package/dist/workspace/memory/memory-empty.js +28 -0
  456. package/dist/workspace/memory/memory-history.d.ts +27 -0
  457. package/dist/workspace/memory/memory-history.js +108 -0
  458. package/dist/workspace/memory/memory-labels.d.ts +16 -0
  459. package/dist/workspace/memory/memory-labels.js +47 -0
  460. package/dist/workspace/memory/memory-page-list.d.ts +34 -0
  461. package/dist/workspace/memory/memory-page-list.js +156 -0
  462. package/dist/workspace/memory/memory-reader.d.ts +58 -0
  463. package/dist/workspace/memory/memory-reader.js +123 -0
  464. package/dist/workspace/memory/memory-view.d.ts +21 -0
  465. package/dist/workspace/memory/memory-view.js +124 -0
  466. package/dist/workspace/memory/remember-popover.d.ts +19 -0
  467. package/dist/workspace/memory/remember-popover.js +61 -0
  468. package/dist/workspace/memory/remember-this.d.ts +12 -0
  469. package/dist/workspace/memory/remember-this.js +89 -0
  470. package/dist/workspace/memory/source-mark.d.ts +18 -0
  471. package/dist/workspace/memory/source-mark.js +79 -0
  472. package/dist/workspace/memory/used-memory-chip.d.ts +14 -0
  473. package/dist/workspace/memory/used-memory-chip.js +61 -0
  474. package/dist/workspace/new/advanced-fields.d.ts +2 -1
  475. package/dist/workspace/new/advanced-fields.js +2 -2
  476. package/dist/workspace/new/source-param.d.ts +1 -1
  477. package/dist/workspace/new/source-param.js +3 -1
  478. package/dist/workspace/new/use-create-workspace.d.ts +8 -10
  479. package/dist/workspace/new/use-create-workspace.js +3 -3
  480. package/dist/workspace/projects/onboarding/app-logo.d.ts +7 -2
  481. package/dist/workspace/projects/onboarding/app-logo.js +6 -13
  482. package/dist/workspace/projects/policies-panel.js +5 -3
  483. package/dist/workspace/review/review-actions.d.ts +4 -2
  484. package/dist/workspace/review/review-actions.js +8 -2
  485. package/dist/workspace/review/review-center.js +11 -7
  486. package/dist/workspace/review/review-detail.d.ts +10 -0
  487. package/dist/workspace/review/review-detail.js +101 -13
  488. package/dist/workspace/saved-session-skeleton.d.ts +2 -2
  489. package/dist/workspace/saved-session-skeleton.js +3 -3
  490. package/dist/workspace/session-workspace.js +15 -13
  491. package/dist/workspace/sessions/project-sessions-view.js +3 -2
  492. package/dist/workspace/sessions/sessions-toolbar.d.ts +3 -1
  493. package/dist/workspace/sessions/sessions-toolbar.js +2 -2
  494. package/dist/workspace/sidebar/footer/project-apps-nav.d.ts +5 -0
  495. package/dist/workspace/sidebar/footer/project-apps-nav.js +41 -2
  496. package/dist/workspace/sidebar/footer/project-artifacts-nav.d.ts +6 -0
  497. package/dist/workspace/sidebar/footer/project-artifacts-nav.js +22 -0
  498. package/dist/workspace/sidebar/footer/project-manifest-upgrade-alert.js +13 -13
  499. package/dist/workspace/sidebar/footer/project-memory-nav.d.ts +7 -0
  500. package/dist/workspace/sidebar/footer/project-memory-nav.js +19 -0
  501. package/dist/workspace/sidebar/nav-row-meta.js +14 -2
  502. package/dist/workspace/sidebar/project-nav-items.js +3 -0
  503. package/dist/workspace/sidebar/project-session-list.js +68 -56
  504. package/dist/workspace/sidebar/project-sidebar.js +9 -2
  505. package/dist/workspace/sidebar/project-spaces-nav.d.ts +8 -0
  506. package/dist/workspace/sidebar/project-spaces-nav.js +69 -0
  507. package/dist/workspace/sidebar/session-brief-hover-card.js +28 -1
  508. package/dist/workspace/sidebar/session-group-order.d.ts +9 -0
  509. package/dist/workspace/sidebar/session-group-order.js +25 -0
  510. package/dist/workspace/sidebar/session-group-sections.d.ts +62 -0
  511. package/dist/workspace/sidebar/session-group-sections.js +267 -0
  512. package/dist/workspace/sidebar/session-list-chrome.d.ts +28 -0
  513. package/dist/workspace/sidebar/session-list-chrome.js +50 -0
  514. package/dist/workspace/spaces/channel-glyph.d.ts +5 -0
  515. package/dist/workspace/spaces/channel-glyph.js +6 -0
  516. package/dist/workspace/spaces/channel-setup.d.ts +16 -0
  517. package/dist/workspace/spaces/channel-setup.js +105 -0
  518. package/dist/workspace/spaces/channels-onboarding.d.ts +13 -0
  519. package/dist/workspace/spaces/channels-onboarding.js +37 -0
  520. package/dist/workspace/spaces/create-channel-dialog.d.ts +16 -0
  521. package/dist/workspace/spaces/create-channel-dialog.js +158 -0
  522. package/dist/workspace/spaces/private-channels-not-in.d.ts +9 -0
  523. package/dist/workspace/spaces/private-channels-not-in.js +69 -0
  524. package/dist/workspace/spaces/space-agents.d.ts +10 -0
  525. package/dist/workspace/spaces/space-agents.js +10 -0
  526. package/dist/workspace/spaces/space-details-dialog.d.ts +20 -0
  527. package/dist/workspace/spaces/space-details-dialog.js +176 -0
  528. package/dist/workspace/spaces/space-link-label.d.ts +49 -0
  529. package/dist/workspace/spaces/space-link-label.js +73 -0
  530. package/dist/workspace/spaces/space-links.d.ts +19 -0
  531. package/dist/workspace/spaces/space-links.js +230 -0
  532. package/dist/workspace/spaces/space-members.d.ts +46 -0
  533. package/dist/workspace/spaces/space-members.js +182 -0
  534. package/dist/workspace/spaces/space-roster.d.ts +15 -0
  535. package/dist/workspace/spaces/space-roster.js +44 -0
  536. package/dist/workspace/spaces/space-threads-tab.d.ts +56 -0
  537. package/dist/workspace/spaces/space-threads-tab.js +156 -0
  538. package/dist/workspace/spaces/space-timeline-view.d.ts +254 -0
  539. package/dist/workspace/spaces/space-timeline-view.js +235 -0
  540. package/dist/workspace/spaces/space-timeline.d.ts +106 -0
  541. package/dist/workspace/spaces/space-timeline.js +183 -0
  542. package/dist/workspace/spaces/space-triggers.d.ts +13 -0
  543. package/dist/workspace/spaces/space-triggers.js +78 -0
  544. package/dist/workspace/spaces/space-view.d.ts +37 -0
  545. package/dist/workspace/spaces/space-view.js +436 -0
  546. package/package.json +31 -32
  547. package/skills/kortix-ui/SKILL.md +3 -3
  548. package/skills/kortix-ui/references/custom-dashboard.md +3 -3
  549. package/skills/kortix-ui/references/modules.md +28 -4
  550. package/skills/kortix-ui/references/theming.md +1 -1
  551. package/dist/customize/agents/agent-nav.prototype.d.ts +0 -35
  552. package/dist/customize/agents/agent-nav.prototype.js +0 -95
  553. package/dist/customize/connectors/catalog/merge-search.d.ts +0 -10
  554. package/dist/customize/connectors/catalog/merge-search.js +0 -26
  555. package/dist/customize/connectors/detail/find-easy-connect-app.d.ts +0 -29
  556. package/dist/customize/connectors/detail/find-easy-connect-app.js +0 -22
  557. package/dist/customize/migrate-to-v2/use-migrate-to-v2.d.ts +0 -9
  558. package/dist/customize/migrate-to-v2/use-migrate-to-v2.js +0 -24
  559. package/dist/customize/sections/connector-connection-header.d.ts +0 -36
  560. package/dist/customize/sections/connector-connection-header.js +0 -33
  561. package/dist/customize/sections/connector-connection-modal.d.ts +0 -34
  562. package/dist/customize/sections/connector-connection-modal.js +0 -72
  563. package/dist/customize/sections/discover-catalogue-card.d.ts +0 -19
  564. package/dist/customize/sections/discover-catalogue-card.js +0 -26
  565. package/dist/customize/sections/discover-catalogue-detail.d.ts +0 -15
  566. package/dist/customize/sections/discover-catalogue-detail.js +0 -24
  567. package/dist/customize/sections/discover-catalogue.d.ts +0 -17
  568. package/dist/customize/sections/discover-catalogue.js +0 -132
  569. package/dist/customize/sections/llm-provider/provider-access-menu.d.ts +0 -10
  570. package/dist/customize/sections/llm-provider/provider-access-menu.js +0 -23
  571. package/dist/files/project/components/drive-empty-art.d.ts +0 -2
  572. package/dist/files/project/components/drive-empty-art.js +0 -5
  573. package/dist/internal/hooks/use-media-query.d.ts +0 -2
  574. package/dist/internal/share/public-share-link-button.d.ts +0 -14
  575. package/dist/internal/share/public-share-link-button.js +0 -17
  576. /package/dist/{internal/hooks → hooks}/use-media-query.js +0 -0
@@ -1,25 +1,33 @@
1
1
  'use client';
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { DetailPageShell } from './detail-page-shell.js';
4
- import { getDiscoverConnector, getProjectDetail, listConnectors } from '@kortix/sdk';
4
+ import { ConnectorLogo } from '../../../internal/connector-logo/connector-logo.js';
5
+ import { ChannelHeroLogoInHeader } from '../../sections/component/channel-hero-frame.js';
6
+ import { discoverLogoSource } from '../../../internal/connector-logo/connector-logo-source.js';
7
+ import { ComputerAppPage } from './computer-app-page.js';
8
+ import { getDiscoverConnector, getDiscoverConnectorTools, getProjectDetail, listConnections, listConnectors, } from '@kortix/sdk';
5
9
  import { contract, FRESHNESS, qk, useProjectAccountId } from '@kortix/sdk/react';
6
- import { ArrowSquareOutIcon, CaretLeftIcon, CaretRightIcon, GlobeIcon, PlugIcon, } from '@phosphor-icons/react';
10
+ import { ArrowSquareOutIcon, CaretLeftIcon, CaretRightIcon, DotsThreeIcon, GlobeIcon, PlugIcon, } from '@phosphor-icons/react';
7
11
  import { useQuery } from '@tanstack/react-query';
8
12
  import { lazyClient } from '../../../lib/lazy-client.js';
9
- import { UiLink as Link, useUiSearchParams } from '../../../providers/ui-provider.js';
10
- import { useState } from 'react';
13
+ import { UiLink as Link, useUiRouter, useUiSearchParams } from '../../../providers/ui-provider.js';
14
+ import { Fragment, useEffect, useState } from 'react';
11
15
  import { Badge } from '../../../primitives/badge.js';
16
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '../../../primitives/dropdown-menu.js';
17
+ import { humanizeToolName, toolBucket } from '../tools/tool-groups.js';
18
+ import { connectorAccounts } from './use-connector-detail.js';
12
19
  import { Button } from '../../../primitives/button.js';
13
- import { EntityAvatar } from '../../../primitives/entity-avatar.js';
14
20
  import { Skeleton } from '../../../primitives/skeleton.js';
15
21
  import { EmptyState } from '../../../primitives/empty-state.js';
16
22
  import { ErrorState } from '../../../primitives/error-state.js';
17
- import { appNameKey, catalogEntryConnectors, discoverEntryIcon, } from '../catalog/catalog-entry.js';
23
+ import { appNameKey, catalogEntryConnectors, connectToolkitApp, } from '../catalog/catalog-entry.js';
18
24
  import { listConnectCatalogPage, useConnectProviderStatus, } from '../catalog/use-catalog.js';
19
25
  import { connectorDisplayName, connectorSummary, } from '../connector-filter.js';
20
- import { appRefFromLocation, connectorHref, connectorsHref, } from '../connector-routes.js';
26
+ import { COMPUTER_APP_ID, appHref, appRefFromLocation, connectorHref, connectorsHref, waysFromParams, } from '../connector-routes.js';
21
27
  import { discoverInstallTarget, easyConnectInstallTarget, } from '../install/install.js';
22
28
  import { InstallButton } from '../install/install-menu.js';
29
+ import { InstallDialog, wayDescription } from '../install/install-dialog.js';
30
+ import { wayKindLabel } from '../install/way-kind.js';
23
31
  import { installableVariants, surfaceInstallName, } from '../install/pick-surface.js';
24
32
  import { mcpServerFor } from '../install/mcp-first.js';
25
33
  import { useInstall } from '../install/use-install.js';
@@ -28,7 +36,6 @@ import { useTranslations } from '../../../i18n/index.js';
28
36
  import { PROJECT_ACTIONS } from '../../../internal/lib/project-actions.js';
29
37
  import { useProjectCan } from '../../../internal/lib/use-project-can.js';
30
38
  import { connectorRunsOver, connectorStatusTone } from './connector-status.js';
31
- import { findEasyConnectApp } from './find-easy-connect-app.js';
32
39
  import { ProviderInfo, providerName } from './provider-info.js';
33
40
  import { ConnectorStatusBadge } from './status-badge.js';
34
41
  /** The same column as the connector page beside this one (`connector-page.tsx`). */
@@ -36,23 +43,9 @@ import { ConnectorStatusBadge } from './status-badge.js';
36
43
  const SURFACE_ROW = 'flex items-center gap-3 px-4 py-3';
37
44
  /** One bordered group of rows, divided. Shared by both lists on the page. */
38
45
  const ROW_GROUP = 'bg-popover divide-y overflow-hidden rounded-md border';
39
- const surfaceLabel = (kind) => (kind === 'openapi' ? 'OpenAPI' : kind.toUpperCase());
40
- /**
41
- * The app page's icon tile (`ConnectorAppIcon`, size `lg`): the resolved
42
- * favicon, or the glyph tile when the record has none — and the same glyph
43
- * tile when the URL fails to load, which used to render the browser's
44
- * broken-image glyph beside the title. Mirrors the catalogue card's
45
- * `ConnectorIcon`. The latch is per URL (`failedUrl`), so the late-arriving
46
- * managed logo — which swaps the URL — gets a fresh try without a call-site
47
- * key.
48
- */
49
- function AppIcon({ icon, name }) {
50
- const [failedUrl, setFailedUrl] = useState(null);
51
- if (!icon || failedUrl === icon) {
52
- return _jsx(EntityAvatar, { icon: GlobeIcon, size: "lg", label: name });
53
- }
54
- return (_jsx("span", { className: "flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-sm", children: _jsx("img", { src: icon, alt: "", width: 36, height: 36, referrerPolicy: "no-referrer", className: "size-9 object-contain", onError: () => setFailedUrl(icon) }) }));
55
- }
46
+ const surfaceLabel = (kind) => wayKindLabel(kind);
47
+ /** Tools shown before "Show all". */
48
+ const TOOLS_PREVIEW = 40;
56
49
  /**
57
50
  * `/projects/<id>/customize/connectors/<app>` — one catalogue app: what it is,
58
51
  * the one Install button, the connectors this project already has for it, and
@@ -61,13 +54,23 @@ function AppIcon({ icon, name }) {
61
54
  * It replaces the surface-picker modal. A non-default surface is chosen only
62
55
  * here, under "Ways to connect".
63
56
  */
57
+ const ChannelsSection = lazyClient(() => import('../../sections/view/channels-view.js').then((m) => m.ChannelsSection));
64
58
  const AddMcpServerDialog = lazyClient(() => import('../add-mcp/add-mcp-server-dialog.js').then((m) => m.AddMcpServerDialog));
65
59
  export function AppPage({ projectId, appSegment }) {
60
+ const search = useUiSearchParams();
61
+ if (search?.get('id') === COMPUTER_APP_ID)
62
+ return _jsx(ComputerAppPage, { projectId: projectId });
63
+ return _jsx(CatalogAppPage, { projectId: projectId, appSegment: appSegment });
64
+ }
65
+ function CatalogAppPage({ projectId, appSegment }) {
66
66
  const t = useTranslations('connectorPages');
67
67
  const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
68
68
  const tSharing = useTranslations('accessSharing');
69
69
  const search = useUiSearchParams();
70
+ const router = useUiRouter();
70
71
  const app = appRefFromLocation(appSegment, search);
72
+ // `?ways=1`: stay on this page for an installed app (another profile).
73
+ const ways = waysFromParams(search);
71
74
  const accountId = useProjectAccountId(projectId);
72
75
  const canWrite = useProjectCan(projectId, PROJECT_ACTIONS.PROJECT_CONNECTOR_WRITE, { accountId }).allowed ===
73
76
  true;
@@ -76,6 +79,12 @@ export function AppPage({ projectId, appSegment }) {
76
79
  queryFn: () => listConnectors(projectId, { includeSchemas: false }),
77
80
  ...contract(FRESHNESS.connectors),
78
81
  });
82
+ // Same key and fetcher as the Accounts tab: the "Installed" rows count accounts like it.
83
+ const connectionsQuery = useQuery({
84
+ queryKey: ['connections', projectId],
85
+ queryFn: () => listConnections(projectId),
86
+ staleTime: 30_000,
87
+ });
79
88
  const projectQuery = useQuery({
80
89
  queryKey: qk.project.detail(projectId),
81
90
  queryFn: () => getProjectDetail(projectId),
@@ -85,18 +94,46 @@ export function AppPage({ projectId, appSegment }) {
85
94
  const everyoneLabel = projectName
86
95
  ? tSharing('everyone', { project: projectName })
87
96
  : tSharing('visibilityEveryone');
88
- const { appQuery, waiting, resolved, managed, detail, provider } = useAppData(projectId, app);
89
- const { install, pendingKey, setPendingKey } = useInstall(projectId);
97
+ // Which way's tools the Tools section lists: the recommended one until the
98
+ // user picks another under "Ways to connect".
99
+ const [toolsWay, setToolsWay] = useState(null);
100
+ const [allTools, setAllTools] = useState(false);
101
+ const { appQuery, resolved, managed, detail, provider } = useAppData(projectId, app);
102
+ const shownWay = resolved?.surfaces.find((surface) => surface.variantId !== null && surface.variantId === toolsWay) ??
103
+ resolved?.surfaces.find((surface) => surface.variantId !== null) ??
104
+ null;
105
+ const toolsQuery = useQuery({
106
+ queryKey: ['discover-connector-tools', projectId, detail?.item.id ?? null, shownWay?.variantId ?? null],
107
+ queryFn: () => getDiscoverConnectorTools(projectId, detail?.item.id ?? '', shownWay?.variantId ?? undefined),
108
+ enabled: Boolean(detail && shownWay?.variantId),
109
+ staleTime: 15 * 60_000,
110
+ retry: false,
111
+ });
112
+ const { install, ask, confirm, request, setRequest, pendingKey, setPendingKey } = useInstall(projectId);
90
113
  // The app's own MCP server, when Install connects through it (one-click
91
114
  // sign-in): the MCP dialog opens for it instead of the managed app.
92
115
  const [mcpApp, setMcpApp] = useState(null);
93
116
  // Which of this page's Install controls started the running install, so only
94
117
  // that one shows progress; the others are disabled until it ends.
95
118
  const [pendingControl, setPendingControl] = useState(null);
119
+ // One page per app: once the project has exactly one profile of it, the
120
+ // app's page is that connector's page. A Kortix channel keeps its own page.
121
+ const installedOnce = app && resolved && detail?.item.kind !== 'kortix' && !ways
122
+ ? catalogEntryConnectors(connectorsQuery.data?.connectors ?? [], {
123
+ source: app.source,
124
+ slug: app.slug,
125
+ name: resolved.name,
126
+ })
127
+ : [];
128
+ const redirectTo = installedOnce.length === 1 && app ? connectorHref(projectId, installedOnce[0].slug, { app }) : null;
129
+ useEffect(() => {
130
+ if (redirectTo)
131
+ router.replace(redirectTo);
132
+ }, [redirectTo, router]);
96
133
  // The connector list is part of the page, not a late addition: Install reads
97
134
  // it to reuse the app's connector, and a list that is still empty would make
98
135
  // it create a second one.
99
- if (waiting || (appQuery && (appQuery.isPending || connectorsQuery.isPending))) {
136
+ if (redirectTo || (appQuery && (appQuery.isPending || connectorsQuery.isPending))) {
100
137
  return (_jsxs(DetailPageShell, { busy: true, children: [_jsx(Skeleton, { className: "h-4 w-24 rounded-sm py-0" }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Skeleton, { className: "size-10 py-0" }), _jsx(Skeleton, { className: "h-6 w-48 rounded-sm py-0" })] }), _jsx(Skeleton, { className: "h-16 w-full py-0" }), _jsx(Skeleton, { className: "h-16 w-full py-0" })] }));
101
138
  }
102
139
  // A failed background refetch keeps its data, and the page with it.
@@ -113,32 +150,68 @@ export function AppPage({ projectId, appSegment }) {
113
150
  // `catalogEntryConnectors` reads only `source`, `slug`, and `name`.
114
151
  const entry = { source: app.source, slug: app.slug, name: resolved.name };
115
152
  const inProject = catalogEntryConnectors(connectors, entry);
153
+ // `GMAIL_SEND_EMAIL` reads "Send email" on the Gmail page, as on the Tools tab.
154
+ const appNames = [app.slug, resolved.name];
116
155
  const installing = pendingKey === app.slug;
156
+ /** Install one way: a one-click MCP server opens the MCP dialog, which
157
+ * names the profile; every other way asks for the name first. */
158
+ const startInstall = (key, surface, name, asNewProfile = false) => {
159
+ const target = surface.target;
160
+ if (!target)
161
+ return;
162
+ setPendingControl(key);
163
+ // The way the user picked is the way installed.
164
+ const mcpUrl = surface.kind === 'mcp' && surface.oneClick ? surface.url : null;
165
+ const askName = () => ask({ target, way: { kind: surface.kind, oneClick: surface.oneClick }, connectors, app, asNewProfile });
166
+ if (!mcpUrl) {
167
+ askName();
168
+ return;
169
+ }
170
+ setPendingKey(app.slug);
171
+ void mcpServerFor(projectId, { name, directMcpUrl: mcpUrl }).then((server) => {
172
+ setPendingKey(null);
173
+ if (server)
174
+ setMcpApp(server);
175
+ else
176
+ askName();
177
+ });
178
+ };
117
179
  /** `name` tells the page's Install controls apart for assistive tech; `key`
118
180
  * tells them apart for the progress indicator. */
119
- const installMenu = (key, target, variant, name) => canWrite ? (_jsx(InstallButton, { label: t('install'), "aria-label": t('installNamed', { name }), variant: variant, onInstall: () => {
120
- setPendingControl(key);
121
- const mcpUrl = target.managed ? managed?.directMcpUrl : null;
122
- if (!mcpUrl) {
123
- install(target, { connectors, app });
124
- return;
125
- }
126
- setPendingKey(app.slug);
127
- void mcpServerFor(projectId, { name: name, directMcpUrl: mcpUrl }).then((server) => {
128
- setPendingKey(null);
129
- if (server)
130
- setMcpApp(server);
131
- else
132
- install(target, { connectors, app });
133
- });
134
- }, pending: installing && pendingControl === key, disabled: installing })) : null;
181
+ // The profile this way already installed, if any: its action is Add
182
+ // account on that profile, never a second profile.
183
+ const installedFor = (surface) => surface.target ? inProject.find((connector) => connector.provider === surface.target?.provider) ?? null : null;
184
+ const installMenu = (key, surface, variant, name) => {
185
+ const installed = installedFor(surface);
186
+ if (installed && !surface.setupHref) {
187
+ const addAccount = (_jsx(Button, { asChild: true, size: "sm", variant: variant, className: "shrink-0", children: _jsx(Link, { href: connectorHref(projectId, installed.slug, { app, addAccount: true }), "aria-label": t('addAccountNamed', { name: connectorDisplayName(installed) }), children: tSharing('addAccount') }) }));
188
+ // The header holds one action. A second profile of an installed way is
189
+ // rare and quiet: the row's overflow menu, never a button beside Add account.
190
+ if (key === 'header' || !canWrite)
191
+ return addAccount;
192
+ return (_jsxs("span", { className: "flex shrink-0 items-center gap-1", children: [addAccount, _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { type: "button", size: "icon-sm", variant: "ghost", "aria-label": t('wayMoreNamed', { name }), disabled: installing, children: _jsx(DotsThreeIcon, { className: "size-4 shrink-0" }) }) }), _jsx(DropdownMenuContent, { align: "end", children: _jsx(DropdownMenuItem, { onSelect: () => startInstall(key, surface, name, true), children: t('anotherProfileTitle') }) })] })] }));
193
+ }
194
+ return surface.setupHref ? (_jsx(Button, { asChild: true, size: "sm", variant: variant, className: "shrink-0", children: _jsx(Link, { href: surface.setupHref, "aria-label": t('setUpNamed', { name }), children: t('waySetUp') }) })) : canWrite ? (_jsx(InstallButton, { label: t('install'), "aria-label": t('installNamed', { name }), variant: variant, onInstall: () => startInstall(key, surface, name), pending: installing && pendingControl === key, disabled: installing })) : null;
195
+ };
135
196
  const primary = resolved.surfaces[0] ?? null;
136
- const waysCount = resolved.surfaces.length + resolved.references.length;
197
+ // A Kortix channel's own page draws the channel as its hero; the ways list
198
+ // keeps only the other ways (the vendor's MCP server, Composio, the API).
199
+ // Computer has a page of its own (`ComputerAppPage`).
200
+ const kortixApp = detail?.item.kind === 'kortix' ? (detail.item.kortix?.app ?? null) : null;
201
+ const channelPlatform = kortixApp && kortixApp !== 'computer' ? kortixApp : null;
202
+ const waySurfaces = channelPlatform
203
+ ? resolved.surfaces.filter((surface) => surface.kind !== 'kortix')
204
+ : resolved.surfaces;
137
205
  const infoCells = [];
138
206
  // The Provider cell follows the primary way to connect: the app itself for
139
- // its API/MCP server, Kortix for a managed-only app.
140
- const managedOnly = managed && !detail;
141
- const managedBy = managedOnly ? connectorRunsOver(provider) : null;
207
+ // its API/MCP server, the partner for a managed way.
208
+ const managedBy = primary?.kind === 'composio'
209
+ ? 'Composio'
210
+ : primary?.kind === 'kortix'
211
+ ? 'Kortix'
212
+ : primary?.kind === 'pipedream'
213
+ ? connectorRunsOver(provider)
214
+ : null;
142
215
  if (primary)
143
216
  infoCells.push({
144
217
  key: 'provider',
@@ -161,13 +234,38 @@ export function AppPage({ projectId, appSegment }) {
161
234
  infoCells.push({ key: 'events', label: t('infoAppEvents'), value: t('infoAppEventsYes') });
162
235
  }
163
236
  if (primary?.kind)
164
- infoCells.push({ key: 'runs', label: t('infoRunsOver'), value: primary.kind });
165
- if (waysCount > 1)
166
- infoCells.push({ key: 'ways', label: t('waysToConnect'), value: String(waysCount) });
167
- return (_jsxs(DetailPageShell, { children: [_jsx(Button, { asChild: true, variant: "text", size: "sm", className: "-ml-1 w-fit px-0 has-[>svg]:px-0", children: _jsxs(Link, { href: connectorsHref(projectId), children: [_jsx(CaretLeftIcon, { className: "size-3.5 shrink-0" }), tI18nComplete.raw('textc3d2e79ebdd0')] }) }), _jsxs("header", { className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-3", children: [_jsx(AppIcon, { icon: resolved.icon, name: resolved.name }), _jsx("h1", { className: "text-foreground min-w-0 text-xl font-medium text-balance wrap-break-word", children: resolved.name })] }), primary ? (_jsx("div", { className: "shrink-0", children: installMenu('header', primary.target, 'default', resolved.name) })) : null] }), infoCells.length > 0 || resolved.description ? (_jsxs("div", { className: "bg-popover divide-border divide-y overflow-hidden rounded-md border", children: [infoCells.length > 0 ? (_jsx("dl", { className: "flex flex-wrap gap-x-8 gap-y-3 px-4 py-3", children: infoCells.map((cell) => (_jsxs("div", { className: "min-w-0 space-y-0.5", children: [_jsxs("dt", { className: "text-muted-foreground flex h-4 items-center justify-between gap-2 text-xs", children: [_jsx("span", { children: cell.label }), cell.labelAddon] }), _jsx("dd", { className: "text-foreground truncate text-sm font-medium", children: cell.value })] }, cell.key))) })) : null, resolved.description ? (_jsxs("div", { className: "space-y-1.5 px-4 py-4", children: [_jsx("h2", { className: "text-muted-foreground text-xs", children: t('overview') }), _jsx("p", { className: "text-foreground text-sm text-pretty", children: resolved.description })] })) : null] })) : null, inProject.length > 0 ? (_jsxs("section", { className: "space-y-3", children: [_jsxs("div", { className: "space-y-1", children: [_jsx("h2", { className: "text-foreground text-sm font-medium", children: projectName ? t('installedIn', { project: projectName }) : t('installedHere') }), _jsx("p", { className: "text-muted-foreground text-xs", children: t('installedHint') })] }), _jsx("ul", { className: ROW_GROUP, children: inProject.map((connector) => {
168
- const tone = connectorStatusTone(connector);
237
+ infoCells.push({ key: 'runs', label: t('infoRunsOver'), value: wayKindLabel(primary.kind) });
238
+ return (_jsxs(DetailPageShell, { children: [_jsx(Button, { asChild: true, variant: "text", size: "sm", className: "-ml-1 w-fit px-0 has-[>svg]:px-0", children: _jsxs(Link, { href: connectorsHref(projectId), children: [_jsx(CaretLeftIcon, { className: "size-3.5 shrink-0" }), tI18nComplete.raw('textc3d2e79ebdd0')] }) }), _jsxs("header", { className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-3", children: [_jsx(ConnectorLogo, { source: resolved.logo, size: "lg" }), _jsx("h1", { className: "text-foreground min-w-0 text-xl font-medium text-balance wrap-break-word", children: resolved.name })] }), primary && !channelPlatform ? (_jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [resolved.surfaces.length > 1 && !installedFor(primary) ? (_jsx("span", { className: "text-muted-foreground text-xs", children: primary.kind === 'kortix'
239
+ ? t('setUpWhere')
240
+ : t('installsWay', { kind: wayKindLabel(primary.kind) }) })) : null, installMenu('header', primary, 'default', resolved.name) ?? (
241
+ // A member without connector write: say who can, not nothing.
242
+ _jsx("span", { className: "text-muted-foreground text-xs", children: t('askAdminToInstall') }))] })) : null] }), channelPlatform ? (
243
+ // The header above shows the app's logo: the hero below does not repeat it.
244
+ _jsx(ChannelHeroLogoInHeader, { children: _jsx(ChannelsSection, { projectId: projectId, platform: channelPlatform }) })) : null, !channelPlatform && (infoCells.length > 0 || resolved.description) ? (_jsxs("div", { className: "bg-popover divide-border divide-y overflow-hidden rounded-md border", children: [infoCells.length > 0 ? (_jsx("dl", { className: "flex flex-wrap gap-x-8 gap-y-3 px-4 py-3", children: infoCells.map((cell) => (_jsxs("div", { className: "min-w-0 space-y-0.5", children: [_jsxs("dt", { className: "text-muted-foreground flex h-4 items-center justify-between gap-2 text-xs", children: [_jsx("span", { children: cell.label }), cell.labelAddon] }), _jsx("dd", { className: "text-foreground truncate text-sm font-medium", children: cell.value })] }, cell.key))) })) : null, resolved.description ? (_jsxs("div", { className: "space-y-1.5 px-4 py-4", children: [_jsx("h2", { className: "text-muted-foreground text-xs", children: t('overview') }), _jsx("p", { className: "text-foreground text-sm text-pretty", children: resolved.description })] })) : null] })) : null, inProject.length > 0 ? (_jsxs("section", { className: "space-y-3", children: [_jsx("h2", { className: "text-foreground text-sm font-medium", children: projectName ? t('installedIn', { project: projectName }) : t('installedHere') }), _jsx("ul", { className: ROW_GROUP, children: inProject.map((connector) => {
245
+ const tone = connectorStatusTone(connector, connectionsQuery.data ? connectorAccounts(connectionsQuery.data.connections, connector).length : undefined);
169
246
  return (_jsx("li", { children: _jsxs(Link, { href: connectorHref(projectId, connector.slug, { app }), className: "hover:bg-muted/50 flex items-center gap-3 px-4 py-3 transition-colors", children: [_jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "text-foreground block truncate text-sm font-medium", children: connectorDisplayName(connector) }), _jsx("span", { className: "text-muted-foreground block truncate text-xs", children: connectorSummary(connector, providerLabel(connector.provider)) })] }), _jsx("span", { className: "flex w-28 shrink-0 items-center", children: _jsx(ConnectorStatusBadge, { tone: tone }) }), _jsxs("span", { className: "text-muted-foreground flex w-16 shrink-0 items-center justify-end gap-1 text-xs", children: [t('open'), _jsx(CaretRightIcon, { "aria-hidden": true, className: "size-4" })] })] }) }, connector.slug));
170
- }) })] })) : null, resolved.surfaces.length === 0 && resolved.references.length === 0 ? (_jsx(EmptyState, { icon: GlobeIcon, size: "sm", title: tI18nComplete.raw('text363579e1d66b'), description: tI18nComplete.raw('text4d286e47d580') })) : null, resolved.surfaces.length > 1 || resolved.references.length > 0 ? (_jsxs("section", { className: "space-y-3", children: [_jsx("h2", { className: "text-foreground text-sm font-medium", children: t('waysToConnect') }), _jsxs("ul", { className: ROW_GROUP, children: [resolved.surfaces.map((surface) => (_jsxs("li", { className: SURFACE_ROW, children: [_jsxs("span", { className: "flex min-w-0 flex-1 items-center gap-1.5", children: [_jsx("span", { className: "text-foreground truncate text-sm font-medium", children: surface.label }), surface.kind ? (_jsx(Badge, { variant: "muted", size: "xs", children: surface.kind })) : null] }), installMenu(surface.key, surface.target, 'secondary', surface.label)] }, surface.key))), resolved.references.map((reference) => (_jsxs("li", { className: SURFACE_ROW, children: [_jsxs("span", { className: "flex min-w-0 flex-1 items-center gap-1.5", children: [_jsx("span", { className: "text-foreground truncate text-sm font-medium", children: reference.label }), _jsx(Badge, { variant: "muted", size: "xs", children: reference.kind })] }), reference.href ? (_jsx(Button, { asChild: true, variant: "outline", size: "sm", className: "shrink-0", children: _jsxs("a", { href: reference.href, target: "_blank", rel: "noreferrer", children: [tI18nComplete.raw('text7af023c43013'), _jsx(ArrowSquareOutIcon, { className: "size-3.5 shrink-0" })] }) })) : (_jsx(Badge, { variant: "secondary", size: "sm", children: tI18nComplete.raw('textdf0453d185c4') }))] }, reference.key)))] })] })) : null, mcpApp ? (_jsx(AddMcpServerDialog, { projectId: projectId, app: mcpApp, open: true, onOpenChange: (open) => !open && setMcpApp(null), takenSlugs: connectors.map((connector) => connector.slug), onAdded: () => void connectorsQuery.refetch() }, mcpApp.url)) : null] }));
247
+ }) })] })) : null, resolved.surfaces.length === 0 && resolved.references.length === 0 ? (_jsx(EmptyState, { icon: GlobeIcon, size: "sm", title: tI18nComplete.raw('text363579e1d66b'), description: tI18nComplete.raw('text4d286e47d580') })) : null, waySurfaces.length > (channelPlatform ? 0 : 1) || resolved.references.length > 0 ? (_jsxs("section", { className: "space-y-3", children: [_jsx("h2", { className: "text-foreground text-sm font-medium", children: channelPlatform ? t('otherWaysToConnect') : t('waysToConnect') }), waySurfaces.length > 0 ? (_jsx("ul", { className: ROW_GROUP, children: waySurfaces.map((surface) => (_jsxs("li", { className: SURFACE_ROW, children: [_jsxs("span", { className: "min-w-0 flex-1 space-y-0.5", children: [_jsxs("span", { className: "flex min-w-0 flex-wrap items-center gap-1.5", children: [_jsx("span", { className: "text-foreground truncate text-sm font-medium", children: surface.label }), _jsx(Badge, { variant: "muted", size: "xs", children: wayKindLabel(surface.kind) }), surface.oneClick ? (_jsx(Badge, { variant: "secondary", size: "xs", children: t('wayOneClick') })) : null, surface.recommended ? (_jsx(Badge, { variant: "success", size: "xs", children: t('wayRecommended') })) : null] }), _jsx("span", { className: "text-muted-foreground block text-xs text-pretty", children: wayDescription(t, { kind: surface.kind, oneClick: surface.oneClick }, resolved.name) })] }), surface.variantId && detail ? (_jsx(Button, { type: "button", variant: shownWay?.variantId === surface.variantId ? 'secondary' : 'outline-ghost', size: "sm", "aria-pressed": shownWay?.variantId === surface.variantId, onClick: () => {
248
+ setToolsWay(surface.variantId);
249
+ setAllTools(false);
250
+ }, children: t('wayTools') })) : null, installMenu(surface.key, surface, 'secondary', surface.label)] }, surface.key))) })) : null, resolved.references.length > 0 ? (_jsxs("p", { className: "text-muted-foreground text-xs text-pretty", children: [t('otherWaysLead'), ' ', resolved.references.map((reference, index) => (_jsxs(Fragment, { children: [index > 0 ? ', ' : null, reference.href ? (_jsxs("a", { href: reference.href, target: "_blank", rel: "noreferrer", className: "text-foreground inline-flex items-center gap-0.5 underline-offset-4 hover:underline", children: [reference.label, _jsx(ArrowSquareOutIcon, { "aria-hidden": true, className: "size-3 shrink-0" })] })) : (reference.label)] }, reference.key)))] })) : null] })) : null, shownWay ? (_jsxs("section", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-baseline justify-between gap-3", children: [_jsx("h2", { className: "text-foreground text-sm font-medium", children: t('toolsOf', { kind: wayKindLabel(shownWay.kind) }) }), toolsQuery.data ? (_jsx("span", { className: "text-muted-foreground text-xs tabular-nums", children: t('toolsCount', { count: toolsQuery.data.total }) })) : null] }), toolsQuery.isPending ? (_jsx(Skeleton, { className: "h-24 w-full py-0" })) : toolsQuery.isError ? (_jsx("p", { className: "text-muted-foreground text-sm", children: t('toolsUnavailable') })) : toolsQuery.data && toolsQuery.data.tools.length > 0 ? (_jsxs(_Fragment, { children: [_jsx("p", { className: "text-muted-foreground text-xs", children: t(`toolsSource_${toolsQuery.data.source}`) }), groupAppTools(allTools ? toolsQuery.data.tools : toolsQuery.data.tools.slice(0, TOOLS_PREVIEW), appNames).map((group) => (_jsxs("div", { className: "space-y-2", children: [_jsxs("h3", { className: "text-muted-foreground text-xs", children: [tI18nComplete.raw(TOOL_GROUP_LABEL[group.key]), " \u00B7 ", group.tools.length] }), _jsx("ul", { className: ROW_GROUP, children: group.tools.map((tool) => {
251
+ const title = humanizeToolName(tool.name, appNames);
252
+ return (_jsxs("li", { className: "min-w-0 px-4 py-2.5", children: [_jsxs("span", { className: "flex min-w-0 flex-wrap items-baseline gap-x-2", children: [_jsx("span", { className: "text-foreground text-sm font-medium", children: title }), title !== tool.name ? (_jsx("code", { className: "text-muted-foreground max-w-full truncate font-mono text-xs", children: tool.name })) : null] }), tool.description ? (_jsx("span", { className: "text-muted-foreground block truncate text-xs", title: tool.description, children: tool.description })) : null] }, tool.name));
253
+ }) })] }, group.key))), !allTools && toolsQuery.data.tools.length > TOOLS_PREVIEW ? (_jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setAllTools(true), children: t('toolsShowAll', { count: toolsQuery.data.tools.length }) })) : null] })) : (_jsx("p", { className: "text-muted-foreground text-sm", children: t('toolsAfterInstall', { kind: wayKindLabel(shownWay.kind) }) }))] })) : null, request ? (_jsx(InstallDialog, { appName: request.target.appName, way: request.way, open: true, pending: false, onOpenChange: (open) => !open && setRequest(null), onConfirm: confirm }, request.target.appName)) : null, mcpApp ? (_jsx(AddMcpServerDialog, { projectId: projectId, app: mcpApp, open: true, onOpenChange: (open) => !open && setMcpApp(null), takenSlugs: connectors.map((connector) => connector.slug), onAdded: () => void connectorsQuery.refetch() }, mcpApp.url)) : null] }));
254
+ }
255
+ const TOOL_GROUP_LABEL = {
256
+ read: 'textdd28b5cb26fd',
257
+ write: 'texted26c1af81cf',
258
+ unclassified: 'text7c0a91e5b3d2',
259
+ };
260
+ /** A catalogue way's tools in the Tools tab's buckets, by the same rule. */
261
+ function groupAppTools(tools, appNames) {
262
+ const groups = { read: [], write: [], unclassified: [] };
263
+ for (const tool of tools) {
264
+ groups[toolBucket({ path: tool.name, name: tool.name, risk: tool.risk ?? 'unknown' }, appNames)].push(tool);
265
+ }
266
+ return ['read', 'write', 'unclassified']
267
+ .filter((key) => groups[key].length > 0)
268
+ .map((key) => ({ key, tools: groups[key] }));
171
269
  }
172
270
  /** The managed catalogue's `authType` as a `connectorPages` key. */
173
271
  function managedSignIn(authType) {
@@ -185,31 +283,19 @@ function readableCategory(key) {
185
283
  return words.charAt(0).toUpperCase() + words.slice(1);
186
284
  }
187
285
  function useAppData(projectId, app) {
188
- const t = useTranslations('connectorPages');
189
- const managedSlug = app?.source === 'easy-connect' ? app.slug : null;
190
286
  const connectStatus = useConnectProviderStatus(true);
191
287
  const provider = connectStatus.provider ?? 'composio';
192
- // `absent`: this deployment has no managed provider, so the app cannot exist.
193
- // `unknown` proceeds, as the catalogue does (`useCatalog`).
194
- const managedRunnable = managedSlug !== null &&
195
- (connectStatus.state === 'configured' || connectStatus.state === 'unknown');
196
- const managedQuery = useQuery({
197
- queryKey: ['easy-connect-app', projectId, provider, managedSlug],
198
- queryFn: () => findEasyConnectApp(listConnectCatalogPage, { projectId, provider, slug: managedSlug ?? '' }),
199
- enabled: managedRunnable,
200
- staleTime: 5 * 60_000,
201
- });
202
- // One app, both ways to connect. A managed app names its API/MCP twin
203
- // (`directId`); an API/MCP app finds its managed twin by name below.
204
- // Same key as the install hook and the old surface modal: one fetch.
205
- const discoverId = app?.source === 'discover' ? app.id : (managedQuery.data?.directId ?? null);
288
+ // Same key as the install hook: one fetch.
289
+ const discoverId = app?.id ?? null;
206
290
  const discoverQuery = useQuery({
207
291
  queryKey: ['discover-connector-detail', projectId, discoverId],
208
292
  queryFn: () => getDiscoverConnector(projectId, discoverId ?? ''),
209
293
  enabled: discoverId !== null,
210
294
  staleTime: 15 * 60_000,
211
295
  });
212
- const twinName = app?.source === 'discover' ? (discoverQuery.data?.item.name ?? null) : null;
296
+ // The managed (Composio) twin found by name: it adds the sign-in, category
297
+ // and app-event facts, and is a way to connect when the record lists none.
298
+ const twinName = discoverQuery.data?.item.name ?? null;
213
299
  const managedTwinQuery = useQuery({
214
300
  queryKey: ['easy-connect-twin', projectId, provider, twinName],
215
301
  queryFn: async () => {
@@ -227,36 +313,86 @@ function useAppData(projectId, app) {
227
313
  staleTime: 5 * 60_000,
228
314
  });
229
315
  // The query that resolves this app, or `null` when nothing can.
230
- const appQuery = app?.source === 'discover' ? discoverQuery : managedRunnable ? managedQuery : null;
231
- const waiting = managedSlug !== null && connectStatus.state === 'asking';
316
+ const appQuery = app ? discoverQuery : null;
232
317
  const detail = discoverId !== null ? discoverQuery.data : undefined;
233
- const managed = (managedRunnable ? managedQuery.data : managedTwinQuery.data) ?? undefined;
234
- // The managed App as one more way to connect, after the API/MCP surfaces.
235
- const managedSurface = managed
318
+ const managed = managedTwinQuery.data ?? undefined;
319
+ // The managed app as one more way to connect, after the API/MCP surfaces,
320
+ // unless the catalogue already lists it (it ranks every way).
321
+ const listsComposio = detail?.variants.some((variant) => variant.kind === 'composio') === true;
322
+ const managedSurface = managed && !listsComposio
236
323
  ? {
237
324
  key: `managed:${managed.slug}`,
238
- label: t('managedSurfaceLabel', { name: managed.name }),
239
- kind: 'App',
325
+ label: managed.name,
326
+ kind: (provider === 'pipedream' ? 'pipedream' : 'composio'),
240
327
  target: easyConnectInstallTarget(managed),
328
+ oneClick: true,
329
+ recommended: false,
330
+ variantId: null,
331
+ url: null,
241
332
  }
242
333
  : null;
334
+ const installable = detail ? installableVariants(detail.variants) : [];
243
335
  const resolved = detail
244
336
  ? {
245
337
  name: managed?.name ?? detail.item.name,
246
338
  description: detail.item.description ?? managed?.description ?? null,
247
- // The managed logo is sharp where the catalogue's favicon is not.
248
- icon: managed?.imgSrc ?? discoverEntryIcon(detail.item),
339
+ // The catalogue card's source, so the page and the card show one logo.
340
+ logo: discoverLogoSource(detail.item),
341
+ // Server order: best way first, the recommended one marked.
249
342
  surfaces: [
250
- ...installableVariants(detail.variants).map((variant, index) => ({
251
- key: `${variant.kind}:${variant.id}`,
252
- label: variant.name,
253
- kind: surfaceLabel(variant.kind),
254
- target: discoverInstallTarget(surfaceInstallName(detail.item.name, variant, index), variant),
255
- })),
343
+ ...detail.variants.flatMap((variant) => {
344
+ if (variant.kind === 'kortix') {
345
+ return [
346
+ {
347
+ key: `kortix:${variant.id}`,
348
+ label: variant.name,
349
+ kind: 'kortix',
350
+ target: null,
351
+ setupHref: appHref(projectId, { source: 'discover', slug: variant.kortix?.app ?? 'kortix', id: variant.id }),
352
+ oneClick: true,
353
+ recommended: variant.recommended === true,
354
+ variantId: null,
355
+ url: null,
356
+ },
357
+ ];
358
+ }
359
+ if (variant.kind === 'composio') {
360
+ return variant.composio
361
+ ? [
362
+ {
363
+ key: `composio:${variant.id}`,
364
+ label: variant.name,
365
+ kind: 'composio',
366
+ target: easyConnectInstallTarget(connectToolkitApp(variant.composio)),
367
+ oneClick: true,
368
+ recommended: variant.recommended === true,
369
+ variantId: variant.id,
370
+ url: null,
371
+ },
372
+ ]
373
+ : [];
374
+ }
375
+ const index = installable.findIndex((candidate) => candidate.id === variant.id);
376
+ const usable = installable[index];
377
+ if (!usable)
378
+ return [];
379
+ return [
380
+ {
381
+ key: `${variant.kind}:${variant.id}`,
382
+ label: variant.name,
383
+ kind: variant.kind,
384
+ target: discoverInstallTarget(surfaceInstallName(detail.item.name, usable, index), usable),
385
+ oneClick: variant.oneClick === true,
386
+ recommended: variant.recommended === true,
387
+ variantId: variant.id,
388
+ url: variant.url,
389
+ },
390
+ ];
391
+ }),
256
392
  ...(managedSurface ? [managedSurface] : []),
257
393
  ],
258
394
  references: detail.variants
259
- .filter((variant) => !variant.connector)
395
+ .filter((variant) => !variant.connector && variant.kind !== 'composio' && variant.kind !== 'kortix')
260
396
  .map((variant) => ({
261
397
  key: `${variant.kind}:${variant.id}`,
262
398
  label: variant.name,
@@ -264,14 +400,6 @@ function useAppData(projectId, app) {
264
400
  href: variant.docs ?? variant.url,
265
401
  })),
266
402
  }
267
- : managed
268
- ? {
269
- name: managed.name,
270
- description: managed.description,
271
- icon: managed.imgSrc,
272
- surfaces: managedSurface ? [managedSurface] : [],
273
- references: [],
274
- }
275
- : null;
276
- return { appQuery, waiting, resolved, managed, detail, provider };
403
+ : null;
404
+ return { appQuery, resolved, managed, detail, provider };
277
405
  }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * The Computer hero, the same frame as every Kortix channel's: not connected,
3
+ * it pairs this machine (the sidebar's "Connect your computer" flow);
4
+ * connected, it names the machines and opens them. On the Computer page and in
5
+ * the Kortix tab of Connectors.
6
+ */
7
+ export declare function ComputerHero({ projectId }: {
8
+ projectId: string;
9
+ }): import("react").JSX.Element;
10
+ /**
11
+ * `…/connectors/computer?id=native:computer`: the Computer card's page, drawn
12
+ * like a Kortix channel's: the hero, then how it works and what agents may do.
13
+ */
14
+ export declare function ComputerAppPage({ projectId }: {
15
+ projectId: string;
16
+ }): import("react").JSX.Element;
@@ -0,0 +1,39 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { CaretLeftIcon, CaretRightIcon } from '@phosphor-icons/react';
4
+ import { useState } from 'react';
5
+ import { useTranslations } from '../../../i18n/index.js';
6
+ import { ComputerCapabilities, ComputerConnectModal, useProjectComputerAccounts } from '../../../internal/tunnel/computer-connect.js';
7
+ import { Button } from '../../../primitives/button.js';
8
+ import { UiLink as Link } from '../../../providers/ui-provider.js';
9
+ import { ChannelHeroFrame, ChannelHeroStatus } from '../../sections/component/channel-hero-frame.js';
10
+ import { ComputerTerminalMock } from '../../sections/component/channel-mocks.js';
11
+ import { connectorHref, connectorsHref } from '../connector-routes.js';
12
+ import { DetailPageShell } from './detail-page-shell.js';
13
+ /** The facts on how a computer connection works, in the order a person asks them. */
14
+ const HOW_IT_WORKS = ['computerHow1', 'computerHow2', 'computerHow3', 'computerHow4'];
15
+ /**
16
+ * The Computer hero, the same frame as every Kortix channel's: not connected,
17
+ * it pairs this machine (the sidebar's "Connect your computer" flow);
18
+ * connected, it names the machines and opens them. On the Computer page and in
19
+ * the Kortix tab of Connectors.
20
+ */
21
+ export function ComputerHero({ projectId }) {
22
+ const t = useTranslations('connectorPages');
23
+ const tComputers = useTranslations('computers');
24
+ const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
25
+ const [connectOpen, setConnectOpen] = useState(false);
26
+ const { accounts, connectorAlias } = useProjectComputerAccounts(projectId, { refetchInterval: 15_000 });
27
+ const connected = accounts.length > 0;
28
+ const names = accounts.map((account) => account.label?.trim()).filter(Boolean).join(', ');
29
+ return (_jsxs(_Fragment, { children: [_jsx(ChannelHeroFrame, { app: "computer", title: connected ? t('computerConnectedTitle', { count: accounts.length }) : t('computerHeroTitle'), lede: t('computerHeroLede'), status: connected ? _jsx(ChannelHeroStatus, { label: tI18nComplete.raw('text22965568d22a'), detail: names || null }) : undefined, actions: connected ? (_jsxs(_Fragment, { children: [_jsx(Button, { size: "sm", asChild: true, children: _jsxs(Link, { href: connectorHref(projectId, connectorAlias), children: [t('computerManage'), _jsx(CaretRightIcon, { className: "size-3.5 shrink-0" })] }) }), _jsx(Button, { size: "sm", variant: "secondary", onClick: () => setConnectOpen(true), children: t('computerAddAnother') })] })) : (_jsx(Button, { className: "transition-transform active:scale-96", onClick: () => setConnectOpen(true), children: tComputers('connectYourComputer') })), preview: _jsx(ComputerTerminalMock, {}) }), _jsx(ComputerConnectModal, { projectId: projectId, open: connectOpen, onOpenChange: setConnectOpen })] }));
30
+ }
31
+ /**
32
+ * `…/connectors/computer?id=native:computer`: the Computer card's page, drawn
33
+ * like a Kortix channel's: the hero, then how it works and what agents may do.
34
+ */
35
+ export function ComputerAppPage({ projectId }) {
36
+ const t = useTranslations('connectorPages');
37
+ const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
38
+ return (_jsxs(DetailPageShell, { children: [_jsx(Button, { asChild: true, variant: "text", size: "sm", className: "-ml-1 w-fit px-0 has-[>svg]:px-0", children: _jsxs(Link, { href: connectorsHref(projectId), children: [_jsx(CaretLeftIcon, { className: "size-3.5 shrink-0" }), tI18nComplete.raw('textc3d2e79ebdd0')] }) }), _jsx(ComputerHero, { projectId: projectId }), _jsxs("section", { className: "space-y-3", children: [_jsx("h2", { className: "text-foreground text-sm font-medium", children: t('computerHowTitle') }), _jsx("ol", { className: "bg-popover divide-y overflow-hidden rounded-md border", children: HOW_IT_WORKS.map((key, index) => (_jsxs("li", { className: "flex gap-3 px-4 py-3", children: [_jsx("span", { className: "text-muted-foreground w-4 shrink-0 text-sm tabular-nums", children: index + 1 }), _jsx("p", { className: "text-foreground text-sm text-pretty", children: t(key) })] }, key))) })] }), _jsxs("section", { className: "space-y-3", children: [_jsx("h2", { className: "text-foreground text-sm font-medium", children: t('computerCanDoTitle') }), _jsx("div", { className: "bg-popover rounded-md border px-4", children: _jsx(ComputerCapabilities, {}) })] })] }));
39
+ }
@@ -33,7 +33,9 @@ import { AccountInfo } from './account-info.js';
33
33
  export function ConnectorAccounts({ projectId, connector, displayName, canWrite, canManageConnections, onChanged, onRemoved, onStartSession, onSetCredential, showAccountInfo = false, onConnect, addRequest, onAddRequestHandled, }) {
34
34
  const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
35
35
  const isManagedProvider = isManagedConnectorProvider(connector.provider);
36
- const isChannel = connector.provider === 'channel';
36
+ // Email's accounts are inboxes (ConnectionsList's `isEmail` branch); Slack and
37
+ // Teams are one install each.
38
+ const isChannel = connector.provider === 'channel' && connector.platform !== 'email';
37
39
  const showRoster = isManagedProvider && canManageConnections && connector.authorizationStrategy === 'user';
38
40
  if (isChannel) {
39
41
  return (_jsx(ChannelConnectionSection, { projectId: projectId, connector: connector, onChanged: onChanged, onRemoved: onRemoved, canWrite: canWrite }));
@@ -1,6 +1,9 @@
1
1
  import { type AdminConnector, type ConnectorPolicyRule } from '@kortix/sdk';
2
- export declare function ConnectorAdvancedTools({ connector, advancedRules, toolRules, loaded, frozen, busy, saving, sensitivePending, onSave, onSensitive, }: {
2
+ export declare function ConnectorAdvancedTools({ connector, advancedRules, toolRules, loaded, frozen, busy, saving, sensitivePending, onSave, onSensitive, showSensitive, }: {
3
3
  connector: AdminConnector;
4
+ /** The `sensitive` flag belongs to the connector, not to a policy set, so
5
+ * the set view leaves it out. */
6
+ showSensitive?: boolean;
4
7
  advancedRules: ConnectorPolicyRule[];
5
8
  toolRules: ConnectorPolicyRule[];
6
9
  loaded: boolean;
@@ -18,7 +18,7 @@ let patternRowSequence = 0;
18
18
  function nextPatternRowId() {
19
19
  return `pattern:${++patternRowSequence}`;
20
20
  }
21
- export function ConnectorAdvancedTools({ connector, advancedRules, toolRules, loaded, frozen, busy, saving, sensitivePending, onSave, onSensitive, }) {
21
+ export function ConnectorAdvancedTools({ connector, advancedRules, toolRules, loaded, frozen, busy, saving, sensitivePending, onSave, onSensitive, showSensitive = true, }) {
22
22
  const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
23
23
  const hasTools = connector.actions.length > 0;
24
24
  // ── Advanced: pattern rules ─────────────────────────────────────────────
@@ -55,7 +55,7 @@ export function ConnectorAdvancedTools({ connector, advancedRules, toolRules, lo
55
55
  setAdvancedOpen(true);
56
56
  }
57
57
  const savePatternRules = () => onSave([...toolRules, ...draftToRules(draft)]);
58
- return (_jsx(_Fragment, { children: hasTools || advancedRules.length > 0 ? (_jsxs(Disclosure, { variant: "outline", className: "overflow-hidden", open: advancedOpen, onOpenChange: setAdvancedOpen, children: [_jsx(DisclosureTrigger, { variant: "outline", children: _jsxs(Button, { variant: "popover", children: [tI18nComplete.raw('text9f088dbebd6c'), advancedRules.length > 0 ? (_jsx(Badge, { variant: "secondary", size: "sm", children: advancedRules.length })) : null, _jsx("span", { className: "text-muted-foreground ml-auto text-xs font-normal", children: tI18nComplete.raw('text59da2efb2423') })] }) }), _jsx(DisclosureContent, { variant: "outline", contentClassName: "border-border border-t", children: _jsxs("div", { className: "space-y-5 px-4 py-5", children: [_jsxs("div", { className: "flex items-start justify-between gap-4", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-foreground text-sm font-medium", children: tI18nComplete.raw('text594bdd4c19b2') }), _jsx("p", { className: "text-muted-foreground mt-0.5 text-xs text-pretty", children: tI18nComplete.raw('textf900377c2048') })] }), _jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [sensitivePending ? _jsx(Loading, { className: "size-4 shrink-0" }) : null, _jsx(Switch, { checked: connector.sensitive === true, onCheckedChange: onSensitive, disabled: frozen || sensitivePending, "aria-label": tI18nComplete.raw('text594bdd4c19b2') })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: tI18nComplete.raw('text380c0b05bcfc') }), _jsxs("p", { className: "text-muted-foreground text-xs text-pretty", children: [tI18nComplete.raw('textde00adeaf21b'), _jsx("code", { className: "font-mono", children: "delete_*" }), tI18nComplete.raw('text3a13855164e7'), _jsx("code", { className: "font-mono", children: "/^send/i" }), tI18nComplete.raw('texte45481e75a5e')] }), draft.map((row) => (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Input, { value: row.match, placeholder: tI18nComplete.raw('text74ad536dca05'), variant: "popover", size: "xs", className: "flex-1 font-mono", "aria-label": tI18nComplete.raw('text5c9c672f4cd3'), disabled: frozen, onChange: (event) => setDraft((rows) => rows.map((candidate) => candidate.id === row.id
58
+ return (_jsx(_Fragment, { children: hasTools || advancedRules.length > 0 ? (_jsxs(Disclosure, { variant: "outline", className: "overflow-hidden", open: advancedOpen, onOpenChange: setAdvancedOpen, children: [_jsx(DisclosureTrigger, { variant: "outline", children: _jsxs(Button, { variant: "popover", children: [tI18nComplete.raw('text9f088dbebd6c'), advancedRules.length > 0 ? (_jsx(Badge, { variant: "secondary", size: "sm", children: advancedRules.length })) : null, _jsx("span", { className: "text-muted-foreground ml-auto text-xs font-normal", children: tI18nComplete.raw('text59da2efb2423') })] }) }), _jsx(DisclosureContent, { variant: "outline", contentClassName: "border-border border-t", children: _jsxs("div", { className: "space-y-5 px-4 py-5", children: [showSensitive ? (_jsxs("div", { className: "flex items-start justify-between gap-4", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-foreground text-sm font-medium", children: tI18nComplete.raw('text594bdd4c19b2') }), _jsx("p", { className: "text-muted-foreground mt-0.5 text-xs text-pretty", children: tI18nComplete.raw('textf900377c2048') })] }), _jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [sensitivePending ? _jsx(Loading, { className: "size-4 shrink-0" }) : null, _jsx(Switch, { checked: connector.sensitive === true, onCheckedChange: onSensitive, disabled: frozen || sensitivePending, "aria-label": tI18nComplete.raw('text594bdd4c19b2') })] })] })) : null, _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: tI18nComplete.raw('text380c0b05bcfc') }), _jsxs("p", { className: "text-muted-foreground text-xs text-pretty", children: [tI18nComplete.raw('textde00adeaf21b'), _jsx("code", { className: "font-mono", children: "delete_*" }), tI18nComplete.raw('text3a13855164e7'), _jsx("code", { className: "font-mono", children: "/^send/i" }), tI18nComplete.raw('texte45481e75a5e')] }), draft.map((row) => (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Input, { value: row.match, placeholder: tI18nComplete.raw('text74ad536dca05'), variant: "popover", size: "xs", className: "flex-1 font-mono", "aria-label": tI18nComplete.raw('text5c9c672f4cd3'), disabled: frozen, onChange: (event) => setDraft((rows) => rows.map((candidate) => candidate.id === row.id
59
59
  ? { ...candidate, match: event.target.value }
60
60
  : candidate)) }), _jsxs(Select, { value: row.action, disabled: frozen, onValueChange: (next) => setDraft((rows) => rows.map((candidate) => candidate.id === row.id
61
61
  ? {
@@ -0,0 +1,14 @@
1
+ import { type AdminConnector } from '@kortix/sdk';
2
+ /**
3
+ * Agents — which agents can use this connector, and with which rule set. One
4
+ * row per agent: a switch gives or takes the connector, and a picker chooses
5
+ * the rule set (Base rules or one of the connector's sets). Each change
6
+ * commits kortix.yaml (`PUT …/agents/{name}/scope`).
7
+ *
8
+ * Read-only for a caller without both `project.agent.write` and
9
+ * `project.connector.write`: the rows still say who has access.
10
+ */
11
+ export declare function ConnectorAgents({ projectId, connector }: {
12
+ projectId: string;
13
+ connector: AdminConnector;
14
+ }): import("react").JSX.Element;