@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
package/README.md CHANGED
@@ -22,7 +22,7 @@ the component subpaths and the stylesheets. Inside kortix-ai/suna:
22
22
  `"@kortix/ui": "workspace:*"`.
23
23
  `react` and `react-dom` 19 are peers (the PowerPoint preview needs React 19.2.7 or later).
24
24
 
25
- - Public docs: `apps/web/content/docs/sdk/ui.mdx` (https://kortix.com/docs/sdk/ui).
25
+ - Public docs: the "Kortix UI" section of `apps/web/content/docs/developers.mdx` (https://kortix.com/docs/developers#kortix-ui).
26
26
  - Agent skill: `skills/kortix-ui/SKILL.md`, with `references/custom-dashboard.md`
27
27
  (a whole dashboard), `references/modules.md` (every entry, its props, an example) and
28
28
  `references/theming.md` (every theme key). Kortix sessions load the same files
@@ -186,7 +186,7 @@ The root `@kortix/ui` barrel holds only light core primitives. Toasts need one
186
186
 
187
187
  ### Routes
188
188
 
189
- Every URL the components link to comes from one route table, `setUiRoutes` (`@kortix/ui`), called once at module load. The defaults are Kortix's own paths: `project` `/projects/<id>`, `session` `/projects/<id>/sessions/<sessionId>`, `sessions` `/projects/<id>/sessions` (`?view=archived|deleted`), `files` `/projects/<id>/files`, `drive` `/projects/<id>/drive`, `apps` `/projects/<id>/apps`, `members` `/projects/<id>/members`, `sandboxSettings` `/projects/<id>/config?section=sandbox`, `customize` `/projects/<id>/customize/<page>` (agents, skills, connectors, triggers, reminders, models, secrets, review, settings). Return your own path for a page you serve elsewhere. Return `null` for a page you do not serve: every link to it is hidden. `project` and `session` cannot be null.
189
+ Every URL the components link to comes from one route table, `setUiRoutes` (`@kortix/ui`), called once at module load. The defaults are Kortix's own paths: `project` `/projects/<id>`, `session` `/projects/<id>/sessions/<sessionId>`, `sessions` `/projects/<id>/sessions` (`?view=archived|deleted`), `files` `/projects/<id>/files`, `drive` `/projects/<id>/drive`, `apps` `/projects/<id>/apps`, `members` `/projects/<id>/members`, `sandboxSettings` `/projects/<id>/config?section=sandbox`, `customize` `/projects/<id>/customize/<page>` (agents, skills, connectors, triggers, reminders, models, secrets, review, settings), `channel` `/projects/<id>/c/<slug>` and `dm` `/projects/<id>/dm/<agent>` (the sidebar links them while the project's `project_channels` flag is on). Return your own path for a page you serve elsewhere. Return `null` for a page you do not serve: every link to it is hidden. `project`, `session`, `channel` and `dm` cannot be null.
190
190
 
191
191
  ## Modules
192
192
 
@@ -6954,6 +6954,29 @@ function parseManifestText(raw, format) {
6954
6954
  return value;
6955
6955
  }
6956
6956
 
6957
+ // ../shared/src/app-config.ts
6958
+ function appAdminsOnly(app) {
6959
+ return app.services?.find((service) => service.name === "http")?.access === "admins";
6960
+ }
6961
+ function gridApps(apps, canAdmin = true) {
6962
+ const slugs = new Set(apps.map((app) => app.slug));
6963
+ return apps.filter(
6964
+ (app) => app.display?.listed === true && !(app.display?.parent && slugs.has(app.display.parent)) && (canAdmin || !appAdminsOnly(app))
6965
+ );
6966
+ }
6967
+
6968
+ // ../manifest-schema/src/policy-sets.ts
6969
+ var POLICY_SET_NAME_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/;
6970
+ var RESERVED_POLICY_SET_NAME = "base";
6971
+ var POLICY_SETS_UNSUPPORTED_PROVIDERS = ["channel", "computer"];
6972
+ function policySetNameError(name) {
6973
+ if (typeof name !== "string" || !POLICY_SET_NAME_RE.test(name)) {
6974
+ return 'a policy set name is lowercase letters, digits, "_" or "-" (at most 64 characters).';
6975
+ }
6976
+ if (name === RESERVED_POLICY_SET_NAME) return `"base" is reserved: it names the connector's base rules.`;
6977
+ return null;
6978
+ }
6979
+
6957
6980
  // ../manifest-schema/src/slug.ts
6958
6981
  var SLUG_MAX_LENGTH = 128;
6959
6982
  function trimSeparators(value) {
@@ -7622,7 +7645,7 @@ function avatarFill(seed) {
7622
7645
  var NEW_PROMPTS = {
7623
7646
  agent: "I want to configure a new agent for this project. Ask me what it should specialize in and how it should behave, then create its config at `agents/<name>.md`, declare it in `kortix.yaml` under `agents:` with `file: agents/<name>.md` and the access it needs, and open a change request so I can review and merge it.",
7624
7647
  skill: "I want to add a new skill to this project. Ask me what capability it should provide and when it should trigger, then scaffold `skills/<name>/SKILL.md` and open a change request so I can review and merge it.",
7625
- command: "I want to create a new slash command for this project. Ask me what it should do, then add it at `harnesses/opencode/commands/<name>.md` and open a change request so I can review and merge it.",
7648
+ command: "I want to create a new slash command for this project. Ask me what it should do, then add it where pi reads commands (`commands:` in `kortix.yaml` on `kortix_version: 3`, else a prompt template at `harnesses/pi/prompts/<name>.md`) and open a change request so I can review and merge it.",
7626
7649
  connector: "I want to connect an outside service to this project. Ask me which service and what the agents should be able to do with it, then add the connector with the Kortix CLI and tell me what still needs authorizing.",
7627
7650
  secret: "I want to add a secret to this project. Ask me what it is for and which agents need it \u2014 never ask me to paste the value in chat \u2014 then create the secret with the Kortix CLI, grant it to those agents, and tell me where to enter the value.",
7628
7651
  trigger: "I want to set up a trigger for this project. Ask me what should run, which agent should run it, and on what schedule or event, then create it with the Kortix CLI and show me the result."
@@ -8600,6 +8623,7 @@ function readSlackFollowUpHeader(line) {
8600
8623
  }
8601
8624
 
8602
8625
  // ../shared/src/channel-message.ts
8626
+ var CHANNEL_PLATFORMS = ["Slack", "Teams", "Telegram", "Email"];
8603
8627
  var TAIL_MARKERS = [
8604
8628
  /^How to work:/m,
8605
8629
  /^Attached files \(download with/m,
@@ -8678,6 +8702,29 @@ var FOLLOW_UP_HEADERS = [
8678
8702
  { platform: "Teams", header: /^New message from (.+?) in the same Teams conversation:$/m },
8679
8703
  { platform: "Slack", header: /^New message from (.+?) in the same Slack thread:$/m }
8680
8704
  ];
8705
+ var TELEGRAM_FIRST_HEADER = "You received a message on Telegram.";
8706
+ var TELEGRAM_FOLLOW_UP_HEADER = /^New Telegram message from (\S+) in the same chat:$/;
8707
+ var TELEGRAM_TAIL = "\n\nHow to answer:\n- Reply with the ";
8708
+ function readTelegramPrompt(text) {
8709
+ const lineEnd3 = text.indexOf("\n");
8710
+ if (lineEnd3 < 0) return void 0;
8711
+ const header = text.slice(0, lineEnd3).trimEnd();
8712
+ const followUp = TELEGRAM_FOLLOW_UP_HEADER.exec(header);
8713
+ if (header !== TELEGRAM_FIRST_HEADER && !followUp) return void 0;
8714
+ const idLine = /^Message id:[^\n]*\n/m.exec(text);
8715
+ if (!idLine) return void 0;
8716
+ const start = idLine.index + idLine[0].length;
8717
+ const rest = text.slice(start).replace(/^\r?\n/, "");
8718
+ if (/^Message:\r?\n/.test(rest)) return void 0;
8719
+ const tail = text.lastIndexOf(TELEGRAM_TAIL);
8720
+ return {
8721
+ platform: "Telegram",
8722
+ context: "",
8723
+ userName: field(text.slice(lineEnd3, idLine.index), "From") || followUp?.[1] || "unknown",
8724
+ messageText: text.slice(start, tail > start ? tail : text.length).trim(),
8725
+ followUp: followUp !== null
8726
+ };
8727
+ }
8681
8728
  function opensPrompt(text, headerIndex) {
8682
8729
  const before = text.slice(0, headerIndex).trim();
8683
8730
  return before === "" || before.startsWith("NOTE:");
@@ -8687,8 +8734,13 @@ function parseChannelMessage(rawText) {
8687
8734
  if (!text) return void 0;
8688
8735
  const legacy = readLegacyChannelHeader(text);
8689
8736
  if (legacy) {
8690
- const platform = legacy.platform === "Teams" ? "Teams" : legacy.platform === "Telegram" ? "Telegram" : "Slack";
8691
- const messageText = cutAtTail(text.slice(legacy.length));
8737
+ const platform = CHANNEL_PLATFORMS.find((p2) => p2 === legacy.platform) ?? "Slack";
8738
+ const rest = text.slice(legacy.length);
8739
+ const end = rest.lastIndexOf(`
8740
+
8741
+ \u2500\u2500 ${legacy.platform} instructions
8742
+ `);
8743
+ const messageText = end >= 0 ? rest.slice(0, end).trim() : cutAtTail(rest);
8692
8744
  return {
8693
8745
  platform,
8694
8746
  context: legacy.context,
@@ -8697,6 +8749,8 @@ function parseChannelMessage(rawText) {
8697
8749
  followUp: false
8698
8750
  };
8699
8751
  }
8752
+ const telegram = readTelegramPrompt(text);
8753
+ if (telegram) return telegram;
8700
8754
  for (const shape of FIRST_MESSAGE_HEADERS) {
8701
8755
  const m = shape.header.exec(text);
8702
8756
  if (!m || !opensPrompt(text, m.index)) continue;
@@ -8830,6 +8884,12 @@ function utf8Bytes(text) {
8830
8884
  return new TextEncoder().encode(text).length;
8831
8885
  }
8832
8886
 
8887
+ // ../shared/src/space-slug.ts
8888
+ var SPACE_SLUG_MAX = 40;
8889
+ function spaceSlug(name) {
8890
+ return name.toLowerCase().trim().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "").replace(/-+/g, "-").slice(0, SPACE_SLUG_MAX).replace(/^-+|-+$/g, "");
8891
+ }
8892
+
8833
8893
  // ../shared/src/code-language.ts
8834
8894
  var LANGUAGE_ALIASES = {
8835
8895
  // web
@@ -10943,4 +11003,4 @@ smol-toml/dist/index.js:
10943
11003
  *)
10944
11004
  */
10945
11005
 
10946
- export { AVATAR_INK, CARD_TEXT_RATIO, COMMIT_CONFIRM_ATTEMPTS, COMMIT_CONFIRM_DELAY_MS, CREDITS_PER_DOLLAR, CURATED_SECTIONS, KATEX_FENCE_LANGUAGES, LANGUAGE_ALIASES, MAX_PROMPT_ATTACHMENTS_BYTES, MAX_PROMPT_ATTACHMENT_BYTES, MAX_PROMPT_ATTACHMENT_FILES, MAX_PROMPT_UPLOAD_FILENAME_BYTES, META_AGENT_DISPLAY_NAME, META_SANDBOX_SLUG, OTHER, PASTED_INLINE_MAX_BYTES, POPULAR_SECTION, PREVIEW_BUILDING_STATES, PREVIEW_STATE_MESSAGE, PROJECT_GLYPH_COLORS, PROJECT_GLYPH_NAMES, UNKNOWN_RATIO, UPLOAD_LIMITS, autoLinkUrls, avatarFill, buildWebhookSampleRequest, capitalizeWords, cardImageShape, cardListLayout, chalkColors, confirmCommitted, countInSection, dollarsToCredits, editConfigPrompt, errorCode, escapeCurrencyDollars, expandPastedContent, extractReadableHtml, fileTagBlocks, formatFileSize, formatRelative, formatUsdAsCredits, groupIntoSections, hasReferenceDefinitionOutsideFences, humanizeCategory, indexOfIgnoreCase, isAllowedWebPushHost, isAmbiguousCreateFailure, isMermaidCode, isMetaAgentName, languageLabel, looksLikeMarkdown, masonryColumns, neutralizePastedTags, newConfigPrompt, newPastedContentId, normalizeLanguage, normalizeLatexDelimiters, openMarkdownLinkAtEnd, parseBackgroundWorkers, parseBalanceUsd, parseChannelMessage, parseGrepOutput, parseManifestText, parseMemoryEntryOutput, parseMemorySearchOutput, parseReminderPrompt, parseRoomDigest, parseRoomPrompt, parseSessionGetOutput, parseSessionMessagesOutput, parseSessionMetadataOutput, parseSessionSearchHits, parseTriggerEvent, parseTriggerLines, prefersPreviewLink, prepareMarkdownForKatex, prepareMarkdownForMath, promptFileReferenceXml, ptyOutputBlock, ptySpawnedBody, pushTypeOf, referenceHeaders, removeSpans, replaceSpans, resolveRegisteredKey, safeHttpUrl, sandboxMediaPath, sanitizePromptUploadFilename, sectionKeyForCategory, sectionKeysForEntry, sectionTitle, selfClosingTags, serializePromptWithPastes, shouldTilePaste, skillDocumentBody, slackPlainText, slugifySlug, splitPastedContent, stripBashMetadata, stripChatMentionMarkup, stripMarkupForToolOutput, tagBlocks, toolRegistryCandidates, trimPastedText, truncateString, utf8Bytes, withoutEdgeQuotes, xmlBlocks };
11006
+ export { AVATAR_INK, CARD_TEXT_RATIO, COMMIT_CONFIRM_ATTEMPTS, COMMIT_CONFIRM_DELAY_MS, CREDITS_PER_DOLLAR, CURATED_SECTIONS, KATEX_FENCE_LANGUAGES, LANGUAGE_ALIASES, MAX_PROMPT_ATTACHMENTS_BYTES, MAX_PROMPT_ATTACHMENT_BYTES, MAX_PROMPT_ATTACHMENT_FILES, MAX_PROMPT_UPLOAD_FILENAME_BYTES, META_AGENT_DISPLAY_NAME, META_SANDBOX_SLUG, OTHER, PASTED_INLINE_MAX_BYTES, POLICY_SETS_UNSUPPORTED_PROVIDERS, POPULAR_SECTION, PREVIEW_BUILDING_STATES, PREVIEW_STATE_MESSAGE, PROJECT_GLYPH_COLORS, PROJECT_GLYPH_NAMES, UNKNOWN_RATIO, UPLOAD_LIMITS, appAdminsOnly, autoLinkUrls, avatarFill, buildWebhookSampleRequest, capitalizeWords, cardImageShape, cardListLayout, chalkColors, confirmCommitted, countInSection, dollarsToCredits, editConfigPrompt, errorCode, escapeCurrencyDollars, expandPastedContent, extractReadableHtml, fileTagBlocks, formatFileSize, formatRelative, formatUsdAsCredits, gridApps, groupIntoSections, hasReferenceDefinitionOutsideFences, humanizeCategory, indexOfIgnoreCase, isAllowedWebPushHost, isAmbiguousCreateFailure, isMermaidCode, isMetaAgentName, languageLabel, looksLikeMarkdown, masonryColumns, neutralizePastedTags, newConfigPrompt, newPastedContentId, normalizeLanguage, normalizeLatexDelimiters, openMarkdownLinkAtEnd, parseBackgroundWorkers, parseBalanceUsd, parseChannelMessage, parseGrepOutput, parseManifestText, parseMemoryEntryOutput, parseMemorySearchOutput, parseReminderPrompt, parseRoomDigest, parseRoomPrompt, parseSessionGetOutput, parseSessionMessagesOutput, parseSessionMetadataOutput, parseSessionSearchHits, parseTriggerEvent, parseTriggerLines, policySetNameError, prefersPreviewLink, prepareMarkdownForKatex, prepareMarkdownForMath, promptFileReferenceXml, ptyOutputBlock, ptySpawnedBody, pushTypeOf, referenceHeaders, removeSpans, replaceSpans, resolveRegisteredKey, safeHttpUrl, sandboxMediaPath, sanitizePromptUploadFilename, sectionKeyForCategory, sectionKeysForEntry, sectionTitle, selfClosingTags, serializePromptWithPastes, shouldTilePaste, skillDocumentBody, slackPlainText, slugifySlug, spaceSlug, splitPastedContent, stripBashMetadata, stripChatMentionMarkup, stripMarkupForToolOutput, tagBlocks, toolRegistryCandidates, trimPastedText, truncateString, utf8Bytes, withoutEdgeQuotes, xmlBlocks };
@@ -0,0 +1,175 @@
1
+ /**
2
+ * The configuration of one App release: process groups,
3
+ * services (named ports), mounts (volumes), VM sizes, checks and the deploy
4
+ * strategy. `kortix.yaml` `apps.<name>` is the authored form; the
5
+ * CLI resolves it with `resolveAppReleaseConfig`, the API validates it again
6
+ * with `appReleaseConfigIssues` and stores the result on the release, and the
7
+ * deploy engine reads only the resolved form.
8
+ *
9
+ * Pure and dependency-free: the API, the CLI, the SDK and the manifest schema
10
+ * share it.
11
+ */
12
+ export type AppDeployStrategy = 'rolling' | 'immediate' | 'bluegreen' | 'canary';
13
+ export type AppAutoStop = 'off' | 'stop' | 'suspend';
14
+ /** `public`: no gate. `app`: the App's access policy and Kortix sign-in. `admins`: project admins only. */
15
+ export type AppServiceAccess = 'public' | 'app' | 'admins';
16
+ export type AppServiceProtocol = 'http' | 'tcp';
17
+ export interface AppCheck {
18
+ type: 'http' | 'tcp';
19
+ /** Defaults to the service's `internal_port`. */
20
+ port?: number;
21
+ /** http only. */
22
+ path?: string;
23
+ interval_s: number;
24
+ timeout_s: number;
25
+ grace_period_s: number;
26
+ }
27
+ export interface AppService {
28
+ /** `http` is the primary service: it answers on the App's own host. */
29
+ name: string;
30
+ internal_port: number;
31
+ protocol: AppServiceProtocol;
32
+ access: AppServiceAccess;
33
+ auto_stop_machines: AppAutoStop;
34
+ auto_start_machines: boolean;
35
+ min_machines_running: number;
36
+ /** Process groups that serve this port. */
37
+ processes: string[];
38
+ checks: AppCheck[];
39
+ }
40
+ export interface AppMount {
41
+ /** Volume name. Each machine of the group gets its own volume of this name. */
42
+ source: string;
43
+ destination: string;
44
+ initial_size_gb: number;
45
+ snapshot_retention_days: number;
46
+ processes: string[];
47
+ }
48
+ export interface AppVmSize {
49
+ cpu: number;
50
+ memory_gb: number;
51
+ /** Root disk; the data belongs on a mount. */
52
+ disk_gb: number;
53
+ /** Groups this size applies to; empty = every group without a more specific entry. */
54
+ processes: string[];
55
+ }
56
+ export interface AppDeployConfig {
57
+ strategy: AppDeployStrategy;
58
+ /** Runs once per release in a temporary machine (new image, secrets, no mounts) before machines update. */
59
+ release_command: string | null;
60
+ }
61
+ export interface AppReleaseConfig {
62
+ /** Group name → command. `""` runs the image's own command. */
63
+ processes: Record<string, string>;
64
+ services: AppService[];
65
+ mounts: AppMount[];
66
+ vm: AppVmSize[];
67
+ deploy: AppDeployConfig;
68
+ }
69
+ /** The authored form: every field optional, plus the shorthands Apps had before this model. */
70
+ export interface AppReleaseConfigInput {
71
+ processes?: Record<string, string>;
72
+ http_service?: Partial<Omit<AppService, 'name' | 'checks'>> & {
73
+ checks?: Array<Partial<AppCheck>>;
74
+ };
75
+ services?: Array<Partial<Omit<AppService, 'checks'>> & {
76
+ checks?: Array<Partial<AppCheck>>;
77
+ }>;
78
+ mounts?: Array<Partial<AppMount>>;
79
+ vm?: Partial<AppVmSize> | Array<Partial<AppVmSize>>;
80
+ deploy?: Partial<AppDeployConfig>;
81
+ /** Shorthands. */
82
+ port?: number;
83
+ command?: string;
84
+ readiness_path?: string;
85
+ always_on?: boolean;
86
+ resources?: {
87
+ cpu?: number;
88
+ memory_gb?: number;
89
+ disk_gb?: number;
90
+ };
91
+ }
92
+ export interface AppConfigIssue {
93
+ path: string;
94
+ message: string;
95
+ }
96
+ export declare const DEFAULT_PROCESS_GROUP = "app";
97
+ export declare const PRIMARY_SERVICE = "http";
98
+ /** Ports the App supervisor owns inside every machine. */
99
+ export declare const RESERVED_APP_PORTS: readonly [7331, 8080];
100
+ export declare const APP_VM_LIMITS: {
101
+ readonly cpu: {
102
+ readonly min: 1;
103
+ readonly max: 32;
104
+ };
105
+ readonly memory_gb: {
106
+ readonly min: 1;
107
+ readonly max: 128;
108
+ };
109
+ readonly disk_gb: {
110
+ readonly min: 1;
111
+ readonly max: 500;
112
+ };
113
+ };
114
+ export declare const DEFAULT_APP_VM: {
115
+ readonly cpu: 1;
116
+ readonly memory_gb: 2;
117
+ readonly disk_gb: 10;
118
+ };
119
+ export declare const DEFAULT_SNAPSHOT_RETENTION_DAYS = 5;
120
+ export declare const MAX_SNAPSHOT_RETENTION_DAYS = 60;
121
+ /** Platinum caps a volume at 100 GiB (its largest size class). */
122
+ export declare const MAX_VOLUME_GB = 100;
123
+ /**
124
+ * The resolved release config. Shorthands map onto the full fields:
125
+ * `port` → `http_service.internal_port`, `command` → `processes.app`,
126
+ * `readiness_path` → an http check, `always_on` → `auto_stop_machines: off` and
127
+ * `min_machines_running: 1` (`false`: `stop` and 0), `resources` → the default VM.
128
+ * An explicit full field wins over its shorthand.
129
+ */
130
+ export declare function resolveAppReleaseConfig(input?: AppReleaseConfigInput): AppReleaseConfig;
131
+ /** Every rule the deploy engine relies on. Empty = valid. */
132
+ export declare function appReleaseConfigIssues(config: AppReleaseConfig): AppConfigIssue[];
133
+ /** The VM size of one process group: its own entry, else the default entry, else the platform default. */
134
+ export declare function appVmFor(config: AppReleaseConfig, group: string): Omit<AppVmSize, 'processes'>;
135
+ /** The mount a machine of this group gets, or null. */
136
+ export declare function appMountFor(config: AppReleaseConfig, group: string): AppMount | null;
137
+ /** The services a machine of this group serves. */
138
+ export declare function appServicesFor(config: AppReleaseConfig, group: string): AppService[];
139
+ /**
140
+ * Where Kortix shows an App (`kortix.yaml` `apps.<name>.display`). Presentation
141
+ * only: nothing about how the App runs or who may open it changes.
142
+ */
143
+ export interface AppDisplay {
144
+ /** A card in the Apps grid. Default false: an App is on the Apps page only when registered with `listed: true`. A `parent` puts it in that App's tabs instead. */
145
+ listed?: boolean;
146
+ /** The card thumbnail: `live` frames the App, `none` shows an icon. Default `live`. */
147
+ preview?: 'live' | 'none';
148
+ /** The App, by slug, whose detail shows this one as a tab (a backend's admin dashboard). */
149
+ parent?: string;
150
+ }
151
+ /** What the Apps grid reads of an App: the web's `App` and the API's App JSON both fit. */
152
+ export interface GridApp {
153
+ slug: string;
154
+ display?: AppDisplay | null;
155
+ services?: ReadonlyArray<{
156
+ name: string;
157
+ access?: string | null;
158
+ }> | null;
159
+ }
160
+ /**
161
+ * Its primary service is `access: admins` (a backend's admin dashboard): only
162
+ * project admins can open it, so nobody else is shown a card or tab for it.
163
+ */
164
+ export declare function appAdminsOnly(app: GridApp): boolean;
165
+ /**
166
+ * The Apps the grid shows as cards (`display`): registered with `listed: true`,
167
+ * not a tab of a parent in the same list, and not admins-only for a non-admin.
168
+ * A tab whose parent is gone stays reachable as a card. Background Apps (a
169
+ * poller, a bot, a backend) stay out of the grid unless their author registers
170
+ * them. The Apps page, a channel's Apps tab and the channel's Apps count all
171
+ * apply this one rule.
172
+ */
173
+ export declare function gridApps<T extends GridApp>(apps: readonly T[], canAdmin?: boolean): T[];
174
+ /** What is wrong with an authored `display` block of the App `slug`. Paths are relative to the block. */
175
+ export declare function appDisplayIssues(display: unknown, slug: string): AppConfigIssue[];
@@ -1,20 +1,24 @@
1
1
  /**
2
2
  * Recognise a channel-originated user message (Slack, Microsoft Teams,
3
- * Telegram) inside the raw prompt text the API scaffolds for the agent, and
3
+ * Telegram, email) inside the raw prompt text the API scaffolds for the agent, and
4
4
  * pull out what a person wants to see: who wrote it, where, and the words they
5
5
  * typed — not the tenant ids and the `How to work:` instructions.
6
6
  *
7
- * Every shape here is produced by exactly one API renderer:
7
+ * `channelPromptText` below writes the current shape, so its writer and reader
8
+ * are one module. Every other shape is produced by exactly one API renderer:
8
9
  *
9
10
  * | Shape | Producer |
10
11
  * | --- | --- |
12
+ * | `[<Platform> · <where> · message from <sender>]`, the text, then `── <Platform> instructions` after a blank line | `channelPromptText` (this module) |
11
13
  * | `You're answering a message on Slack as a teammate.` | `channels/slack/session.ts` renderAgentPrompt |
12
14
  * | `New message from <user> in Slack channel <channel>, thread <ts>:` | `channels/slack/session.ts` renderFollowUpPrompt |
13
15
  * | `New message from <user> in the same Slack thread:` | the same renderer before 2026-09, kept for old transcripts |
14
16
  * | `You're answering a message on Microsoft Teams as a teammate.` | `channels/teams/session.ts` renderAgentPrompt |
15
17
  * | `New message from <user> in the same Teams conversation:` | `channels/teams/session.ts` renderFollowUpPrompt |
16
- * | `You received a message on Telegram.` | `channels/telegram-webhook.ts` renderAgentPrompt |
17
- * | `[<Platform> · <context> · message from <user>]` | the pre-2026 header, kept so old transcripts still render |
18
+ * | `You received a message on Telegram.` + `Chat:`/`From:`/`Message id:`, the text, `How to answer:` | the Telegram renderer from 2026-10-24 until `channelPromptText`, kept so old transcripts still render |
19
+ * | `New Telegram message from <user> in the same chat:` + the same block | the same renderer, kept so old transcripts still render |
20
+ * | `You received a message on Telegram.` + a `Message:` line | the retired one-session-per-message Telegram webhook (removed 2026-10-24), kept so old transcripts still render |
21
+ * | `[<Platform> · <context> · message from <user>]` with no such delimiter | the pre-2026 header, kept so old transcripts still render |
18
22
  *
19
23
  * The parser is pure and framework-free so `channel-message.test.ts` can pin
20
24
  * each shape against the real prompt text. The web and mobile session views
@@ -25,7 +29,9 @@
25
29
  * attempt. The pre-2026 header regex and the `<at>` strip did: 240k characters
26
30
  * took 22 s and 7 s.
27
31
  */
28
- export type ChannelPlatform = 'Slack' | 'Teams' | 'Telegram';
32
+ /** The platform words a header names. Any other word reads as Slack, as every deployed build reads it. */
33
+ export declare const CHANNEL_PLATFORMS: readonly ["Slack", "Teams", "Telegram", "Email"];
34
+ export type ChannelPlatform = (typeof CHANNEL_PLATFORMS)[number];
29
35
  export interface ChannelMessageInfo {
30
36
  platform: ChannelPlatform;
31
37
  /** Channel / conversation / chat id; empty for a follow-up, which carries none. */
@@ -36,3 +42,26 @@ export interface ChannelMessageInfo {
36
42
  followUp: boolean;
37
43
  }
38
44
  export declare function parseChannelMessage(rawText: string | null | undefined): ChannelMessageInfo | undefined;
45
+ /** What a channel adapter knows about one incoming message; `channelPromptText` writes it. */
46
+ export interface ChannelEnvelope {
47
+ platform: ChannelPlatform;
48
+ /** What a person reads: `@sam`, `Sam Rivera`, `a@b.c`. */
49
+ sender: string;
50
+ /** The chat title, `direct message`, or an email subject. */
51
+ where: string;
52
+ /** The person's words, or a question answer. */
53
+ text: string;
54
+ /** One shell command that answers THIS message. */
55
+ reply: string;
56
+ /** Ids, limits and platform rules: for the agent only, one line each. */
57
+ notes: string[];
58
+ }
59
+ /**
60
+ * The prompt for one channel message. The header line is the one every client
61
+ * build reads (`readLegacyChannelHeader`), the text follows unchanged, and the
62
+ * agent-only lines start at the last `── <Platform> instructions` line, where
63
+ * `parseChannelMessage` cuts.
64
+ */
65
+ export declare function channelPromptText(e: ChannelEnvelope, opts?: {
66
+ revived?: boolean;
67
+ }): string;
@@ -26,3 +26,4 @@ export * from './slack-text';
26
26
  export * from './chat-mention';
27
27
  export * from './webhook-signing';
28
28
  export * from './pasted-content';
29
+ export * from './space-slug';
@@ -12,7 +12,9 @@ export type RuntimeVersions = {
12
12
  bun: string;
13
13
  bunSha256Amd64: string;
14
14
  bunSha256Arm64: string;
15
+ /** @deprecated OpenCode only. OpenCode is sunset (2026-10-23): no new code. See apps/kortix-sandbox-agent-server/src/harness/README.md "OpenCode sunset". */
15
16
  opencode: string;
17
+ /** @deprecated OpenCode only. OpenCode is sunset (2026-10-23): no new code. See apps/kortix-sandbox-agent-server/src/harness/README.md "OpenCode sunset". */
16
18
  opencodeSdk: string;
17
19
  agentBrowser: string;
18
20
  playwright: string;
@@ -35,7 +37,9 @@ export declare const PYTHON_PACKAGE_FLOOR_IMPORTS: Record<string, string>;
35
37
  export declare const BUN_VERSION: string;
36
38
  export declare const BUN_SHA256_AMD64: string;
37
39
  export declare const BUN_SHA256_ARM64: string;
40
+ /** @deprecated OpenCode only. OpenCode is sunset (2026-10-23): no new code. See apps/kortix-sandbox-agent-server/src/harness/README.md "OpenCode sunset". */
38
41
  export declare const OPENCODE_VERSION: string;
42
+ /** @deprecated OpenCode only. OpenCode is sunset (2026-10-23): no new code. See apps/kortix-sandbox-agent-server/src/harness/README.md "OpenCode sunset". */
39
43
  export declare const OPENCODE_SDK_VERSION: string;
40
44
  export declare const OPENCODE_USER_AGENT: string;
41
45
  export declare const AGENT_BROWSER_VERSION: string;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * A channel's slug from its name: lowercase, whitespace runs → `-`, other
3
+ * characters dropped, `-` runs collapsed and trimmed, at most 40 characters.
4
+ * Empty when the name has no `a-z0-9`. The API derives the stored slug with
5
+ * this function, and the create dialog previews it, so the two never differ.
6
+ */
7
+ export declare function spaceSlug(name: string): string;
8
+ /**
9
+ * Where every private channel's folder lives: outside `/Company`, so the
10
+ * project grant on `/Company` and project admins never reach it. Only the
11
+ * channel's members (one grant each) and the channel's own threads do. The
12
+ * folder is named by the channel's id, never its name: a rename moves
13
+ * nothing, and a later channel that takes the name never inherits the folder.
14
+ * Only `/Channels/<space_id>` of a private channel of the project is reserved;
15
+ * any other path under `/Channels` is an ordinary folder (the API's
16
+ * `privateChannelFolderOf`).
17
+ */
18
+ export declare const PRIVATE_CHANNELS_DIR = "/Channels";
19
+ /**
20
+ * A space's two folders in the project's Files (drive paths). A public
21
+ * channel's are shared with the project: `/Company/Channels/<slug>` and its
22
+ * `Memory`. A private channel's are `/Channels/<space_id>` and its `Memory`
23
+ * (pass its id as `privateSpaceId`). A DM's
24
+ * are in the member's own folder: `<personal>/Agents/<agent>` and its
25
+ * memory `<personal>/Memory/<agent>` (the agent folder of the DM's Memory
26
+ * tab, which also lists the rest of `<personal>/Memory`). Null for a DM without a personal folder,
27
+ * and for a name that is not one plain path segment (an agent name is not
28
+ * validated as one when the DM is opened).
29
+ * The API (folder create, rename, the session's /drives/README.md) and the web
30
+ * tabs read this, so both name the same folders.
31
+ */
32
+ export declare function spaceDriveFolders(kind: 'channel' | 'dm', name: string, personalFolder: string | null,
33
+ /** A private channel's id; null for a public channel or a DM. */
34
+ privateSpaceId?: string | null): {
35
+ files: string;
36
+ memory: string;
37
+ } | null;
@@ -18,5 +18,5 @@ import { UiLink as Link } from '../../providers/ui-provider.js';
18
18
  export function AccessDetailShell({ back, avatar, title, badges, meta, actions, tabs, activeTab, onTabChange, loading = false, children, className, }) {
19
19
  const backContent = back ? (_jsxs(_Fragment, { children: [_jsx(CaretLeftIcon, { className: "size-4" }), back.label] })) : null;
20
20
  const backClass = 'text-muted-foreground hover:text-foreground flex w-fit items-center gap-1 text-sm transition-colors';
21
- return (_jsxs("div", { className: cn('mx-auto w-full max-w-6xl space-y-5 pb-10', className), children: [_jsxs("div", { className: "space-y-5", children: [!back ? null : back.href ? (_jsx(Link, { href: back.href, className: backClass, children: backContent })) : (_jsx("button", { type: "button", onClick: back.onClick, className: backClass, children: backContent })), _jsxs("div", { className: "flex min-w-0 items-start gap-3.5", children: [loading ? _jsx(Skeleton, { className: "size-10 rounded-md" }) : avatar, _jsxs("div", { className: "min-w-0 flex-1 space-y-0.5", children: [loading ? (_jsx(Skeleton, { className: "h-6 w-44" })) : (_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx("h2", { className: "text-foreground truncate text-xl font-medium", children: title }), badges] })), meta ? _jsx("div", { className: "text-muted-foreground truncate text-sm", children: meta }) : null] }), actions ? _jsx("div", { className: "flex shrink-0 items-center gap-2", children: actions }) : null] })] }), tabs && tabs.length > 0 ? (_jsxs(Tabs, { value: activeTab, onValueChange: onTabChange, className: "space-y-6", children: [_jsx(TabsList, { type: "underline", className: "flex w-full items-center justify-start", children: tabs.map((tab) => (_jsxs(TabsTrigger, { value: tab.value, className: "w-fit flex-none", children: [tab.label, tab.badge] }, tab.value))) }), children] })) : (_jsx("div", { className: "space-y-6", children: children }))] }));
21
+ return (_jsxs("div", { className: cn('mx-auto w-full max-w-6xl space-y-5 pb-10', className), children: [_jsxs("div", { className: "space-y-5", children: [!back ? null : back.href ? (_jsx(Link, { href: back.href, className: backClass, children: backContent })) : (_jsx("button", { type: "button", onClick: back.onClick, className: backClass, children: backContent })), _jsxs("div", { className: "flex min-w-0 items-center gap-3.5", children: [loading ? _jsx(Skeleton, { className: "size-10 rounded-md" }) : avatar, _jsxs("div", { className: "min-w-0 flex-1 space-y-0.5", children: [loading ? (_jsx(Skeleton, { className: "h-6 w-44" })) : (_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx("h2", { className: "text-foreground truncate text-base leading-6 font-medium", children: title }), badges] })), meta ? _jsx("div", { className: "text-muted-foreground truncate text-sm", children: meta }) : null] }), actions ? _jsx("div", { className: "flex shrink-0 items-center gap-2", children: actions }) : null] })] }), tabs && tabs.length > 0 ? (_jsxs(Tabs, { value: activeTab, onValueChange: onTabChange, className: "space-y-6", children: [_jsx(TabsList, { type: "underline", className: "flex w-full items-center justify-start", children: tabs.map((tab) => (_jsxs(TabsTrigger, { value: tab.value, className: "w-fit flex-none", children: [tab.label, tab.badge] }, tab.value))) }), children] })) : (_jsx("div", { className: "space-y-6", children: children }))] }));
22
22
  }
@@ -13,6 +13,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
13
  //
14
14
  // There is no expiry field here on purpose: when the last narrowing grant
15
15
  // expires, the account silently widens to everyone.
16
+ import { AgentMark } from '../../internal/components/agent-mark.js';
16
17
  import { Button } from '../../primitives/button.js';
17
18
  import { EntityAvatar } from '../../primitives/entity-avatar.js';
18
19
  import { Field, FieldLabel } from '../../primitives/field.js';
@@ -25,7 +26,7 @@ import { useTranslations as useI18nTranslations } from '../../i18n/index.js';
25
26
  import { cn } from '../../internal/lib/utils.js';
26
27
  import { createAssignment, revokeAssignment, shareConnection, } from '@kortix/sdk';
27
28
  import { invalidatePermissionProbes, qk } from '@kortix/sdk/react';
28
- import { LockIcon, RobotIcon, UsersIcon, UsersThreeIcon, XIcon } from '@phosphor-icons/react';
29
+ import { LockIcon, UsersIcon, UsersThreeIcon, XIcon } from '@phosphor-icons/react';
29
30
  import { useMutation, useQueryClient } from '@tanstack/react-query';
30
31
  import { useState } from 'react';
31
32
  import { EMPTY_PRINCIPAL_SELECTION, PrincipalPicker, } from './principal-picker.js';
@@ -176,14 +177,10 @@ export function ShareAccessBody({ open, onOpenChange, accountId, projectId, proj
176
177
  if (save.isPending)
177
178
  return;
178
179
  onOpenChange(next);
179
- }, children: _jsxs(ModalContent, { className: "sm:max-w-md", children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { children: t('shareTitle', { label: object.label }) }), _jsx(ModalDescription, { children: privateOwner ? t('sharePrivateDescription') : t('shareDescription') })] }), _jsxs(ModalBody, { className: "max-h-[60vh] space-y-4 overflow-y-auto", children: [_jsxs(Field, { className: "gap-1.5", children: [_jsx(FieldLabel, { children: t('whoCanUse') }), _jsx("ul", { className: "space-y-2", "data-testid": "share-audience", children: privateOwner ? (_jsx(AudienceRow, { avatar: _jsx(UserAvatar, { email: privateOwner.label, size: "sm" }), label: privateOwner.label, meta: keepOwner ? t('ownerMeta') : t('removedMeta'), removed: !keepOwner, action: keepOwner ? (_jsx(Button, { type: "button", variant: "ghost", size: "icon", className: "size-8 shrink-0", "aria-label": t('remove', { name: privateOwner.label }), disabled: save.isPending, onClick: () => setKeepOwner(false), children: _jsx(XIcon, { className: "size-3.5" }) })) : (_jsx(Button, { type: "button", variant: "ghost", size: "sm", disabled: save.isPending, onClick: () => setKeepOwner(true), children: t('keep') })) })) : current.length === 0 ? (_jsx(AudienceRow, { avatar: _jsx(EntityAvatar, { icon: UsersThreeIcon, label: everyoneLabel, size: "sm" }), label: everyoneLabel, meta: t('everyoneDefaultMeta') })) : (current.map((grant) => {
180
+ }, children: _jsxs(ModalContent, { className: "sm:max-w-md", children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { children: t('shareTitle', { label: object.label }) }), _jsx(ModalDescription, { children: privateOwner ? t('sharePrivateDescription') : t('shareDescription') })] }), _jsxs(ModalBody, { className: "max-h-[60vh] space-y-4 overflow-y-auto", children: [_jsxs(Field, { className: "gap-1.5", children: [_jsx(FieldLabel, { children: t('whoCanUse') }), _jsx("ul", { className: "space-y-2", "data-testid": "share-audience", children: privateOwner ? (_jsx(AudienceRow, { avatar: _jsx(UserAvatar, { email: privateOwner.label, hint: privateOwner.label, size: "sm" }), label: privateOwner.label, meta: keepOwner ? t('ownerMeta') : t('removedMeta'), removed: !keepOwner, action: keepOwner ? (_jsx(Button, { type: "button", variant: "ghost", size: "icon", className: "size-8 shrink-0", "aria-label": t('remove', { name: privateOwner.label }), disabled: save.isPending, onClick: () => setKeepOwner(false), children: _jsx(XIcon, { className: "size-3.5" }) })) : (_jsx(Button, { type: "button", variant: "ghost", size: "sm", disabled: save.isPending, onClick: () => setKeepOwner(true), children: t('keep') })) })) : current.length === 0 ? (_jsx(AudienceRow, { avatar: _jsx(EntityAvatar, { icon: UsersThreeIcon, label: everyoneLabel, hint: everyoneLabel, size: "sm" }), label: everyoneLabel, meta: t('everyoneDefaultMeta') })) : (current.map((grant) => {
180
181
  const isRemoved = removed.has(grant.grant_id);
181
182
  const label = grant.principal_type === 'project' ? everyoneLabel : grant.label;
182
- return (_jsx(AudienceRow, { avatar: grant.principal_type === 'member' ? (_jsx(UserAvatar, { email: grant.label, size: "sm" })) : (_jsx(EntityAvatar, { icon: grant.principal_type === 'group'
183
- ? UsersIcon
184
- : grant.principal_type === 'agent'
185
- ? RobotIcon
186
- : UsersThreeIcon, label: label, size: "sm" })), label: label, meta: isRemoved
183
+ return (_jsx(AudienceRow, { avatar: grant.principal_type === 'member' ? (_jsx(UserAvatar, { email: grant.label, hint: grant.label, size: "sm" })) : grant.principal_type === 'agent' ? (_jsx(AgentMark, { slug: grant.label })) : (_jsx(EntityAvatar, { icon: grant.principal_type === 'group' ? UsersIcon : UsersThreeIcon, label: label, hint: label, size: "sm" })), label: label, meta: isRemoved
187
184
  ? t('removedMeta')
188
185
  : grant.principal_type === 'group'
189
186
  ? t('groupMeta')
@@ -1,5 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { AgentMark } from '../../internal/components/agent-mark.js';
3
4
  import { useTranslations as useI18nTranslations } from '../../i18n/index.js';
4
5
  // AccessDialog — THE modal for every "give / edit access" interaction.
5
6
  //
@@ -909,7 +910,7 @@ function FixedPrincipals({ principals }) {
909
910
  const tI18nComplete = useI18nTranslations('hardcodedUi.i18nComplete');
910
911
  const tAgents = useI18nTranslations('agentPrincipals');
911
912
  return (_jsx("ul", { className: "space-y-2", children: principals.map((principal) => (_jsxs("li", { className: "bg-popover flex items-center gap-2.5 rounded-md border px-3 py-2", children: [principal.avatar ??
912
- (principal.type === 'group' ? (_jsx(EntityAvatar, { label: principal.label, size: "sm" })) : principal.type === 'agent' ? (_jsx(EntityAvatar, { icon: RobotIcon, label: principal.label, size: "sm" })) : (_jsx(UserAvatar, { email: principal.label, size: "sm" }))), _jsx("span", { className: "text-foreground min-w-0 flex-1 truncate text-sm font-medium", children: principal.label }), principal.type === 'group' ? (_jsx(Badge, { variant: "outline", size: "sm", children: tI18nComplete.raw('text34ca0e766088') })) : principal.type === 'agent' ? (_jsx(Badge, { variant: "outline", size: "sm", children: tAgents('agentBadge') })) : null] }, principal.id))) }));
913
+ (principal.type === 'group' ? (_jsx(EntityAvatar, { label: principal.label, hint: principal.label, size: "sm" })) : principal.type === 'agent' ? (_jsx(AgentMark, { slug: principal.label })) : (_jsx(UserAvatar, { email: principal.label, hint: principal.label, size: "sm" }))), _jsx("span", { className: "text-foreground min-w-0 flex-1 truncate text-sm font-medium", children: principal.label }), principal.type === 'group' ? (_jsx(Badge, { variant: "outline", size: "sm", children: tI18nComplete.raw('text34ca0e766088') })) : principal.type === 'agent' ? (_jsx(Badge, { variant: "outline", size: "sm", children: tAgents('agentBadge') })) : null] }, principal.id))) }));
913
914
  }
914
915
  function ScopeLine({ icon: Icon, label, items, }) {
915
916
  return (_jsxs("div", { className: "flex flex-wrap items-center gap-1.5", children: [_jsx(Icon, { className: "text-muted-foreground/70 size-3.5 shrink-0" }), _jsx("span", { className: "text-muted-foreground text-xs font-medium", children: label }), items.map((name) => (_jsx(Badge, { variant: "outline", size: "xs", className: "font-mono", children: name }, name)))] }));
@@ -88,3 +88,14 @@ export interface PrincipalPickerProps {
88
88
  className?: string;
89
89
  }
90
90
  export declare function PrincipalPicker({ scope, selection, kinds, allowInvite, everyone, excludeUserIds, value, onChange, emptyLabel, allExcludedLabel, autoFocus, disabled, searchPlaceholder, className, }: PrincipalPickerProps): import("react").JSX.Element;
91
+ /** One picker row. Exported for the channel "Add members" picker, which moves `highlighted` with the arrow keys. */
92
+ export declare function PickerRow({ selected, selection, highlighted, disabled, onSelect, leading, label, suffix, }: {
93
+ selected: boolean;
94
+ selection: 'single' | 'multi';
95
+ highlighted?: boolean;
96
+ disabled?: boolean;
97
+ onSelect: () => void;
98
+ leading: React.ReactNode;
99
+ label: string;
100
+ suffix?: string;
101
+ }): import("react").JSX.Element;
@@ -1,5 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { AgentMark } from '../../internal/components/agent-mark.js';
3
4
  import { useTranslations } from '../../i18n/index.js';
4
5
  // PrincipalPicker — THE "who is this for?" control.
5
6
  //
@@ -25,7 +26,7 @@ import { useUiHostConfig, useUiViewer } from '../../providers/ui-provider.js';
25
26
  import { cn } from '../../internal/lib/utils.js';
26
27
  import { listAccountMembers, listGroups, listProjectAccess } from '@kortix/sdk';
27
28
  import { contract, qk } from '@kortix/sdk/react';
28
- import { CheckCircleIcon, MagnifyingGlassIcon, RobotIcon, UserPlusIcon, UsersIcon, UsersThreeIcon, } from '@phosphor-icons/react';
29
+ import { CheckCircleIcon, MagnifyingGlassIcon, UserPlusIcon, UsersIcon, UsersThreeIcon, } from '@phosphor-icons/react';
29
30
  import { useQuery } from '@tanstack/react-query';
30
31
  import { useMemo, useState } from 'react';
31
32
  import { principalLabel } from './access-shared.js';
@@ -219,7 +220,7 @@ export function PrincipalPicker({ scope, selection = 'multi', kinds = ['member',
219
220
  : selected.kind === 'member'
220
221
  ? principalLabel(rosterMembers.find((m) => m.user_id === selected.id)) || selected.id
221
222
  : selected.id;
222
- return (_jsxs("div", { className: cn('bg-popover flex items-center gap-2.5 rounded-md border px-3 py-2', className), children: [selected.kind === 'group' ? (_jsx(EntityAvatar, { icon: UsersIcon, label: label, size: "sm" })) : selected.kind === 'agent' ? (_jsx(EntityAvatar, { icon: RobotIcon, label: label, size: "sm" })) : (_jsx(UserAvatar, { email: label, size: "sm" })), _jsx("span", { className: "text-foreground min-w-0 flex-1 truncate text-sm font-medium", children: label }), _jsx(Badge, { variant: "outline", size: "sm", children: selected.kind === 'group'
223
+ return (_jsxs("div", { className: cn('bg-popover flex items-center gap-2.5 rounded-md border px-3 py-2', className), children: [selected.kind === 'group' ? (_jsx(EntityAvatar, { icon: UsersIcon, label: label, hint: label, size: "sm" })) : selected.kind === 'agent' ? (_jsx(AgentMark, { slug: label })) : (_jsx(UserAvatar, { email: label, hint: label, size: "sm" })), _jsx("span", { className: "text-foreground min-w-0 flex-1 truncate text-sm font-medium", children: label }), _jsx(Badge, { variant: "outline", size: "sm", children: selected.kind === 'group'
223
224
  ? 'Group'
224
225
  : selected.kind === 'invite'
225
226
  ? 'Invite'
@@ -258,14 +259,15 @@ export function PrincipalPicker({ scope, selection = 'multi', kinds = ['member',
258
259
  filteredMembers.length === 0 &&
259
260
  filteredAgents.length === 0 &&
260
261
  !inviteCandidate &&
261
- !showEveryone ? (_jsx("p", { className: "text-muted-foreground px-3 py-6 text-center text-xs", children: tI18nComplete.raw('texte8dd87902b91') })) : (_jsxs(_Fragment, { children: [showEveryone && everyone ? (_jsx(PickerRow, { selected: value.everyone === true, selection: selection, disabled: disabled, onSelect: () => pick({ kind: 'everyone', id: scope.kind === 'project' ? scope.projectId : '' }), leading: _jsx(EntityAvatar, { icon: UsersThreeIcon, label: everyone.label, size: "sm" }), label: everyone.label })) : null, inviteCandidate ? (_jsx(PickerRow, { selected: inviteSet.has(inviteCandidate), selection: selection, disabled: disabled, onSelect: () => pick({ kind: 'invite', id: inviteCandidate }), leading: _jsx("span", { className: "border-muted-foreground/40 text-muted-foreground flex size-6 shrink-0 items-center justify-center rounded-full border border-dashed", children: _jsx(UserPlusIcon, { className: "size-3.5" }) }), label: `Invite ${inviteCandidate}`, suffix: tI18nComplete.raw('text10d9e23d0185') })) : null, filteredGroups.length > 0 ? (_jsxs(_Fragment, { children: [_jsx(PickerSectionLabel, { children: tI18nComplete.raw('text39bbb719fa2b') }), filteredGroups.map((group) => (_jsx(PickerRow, { selected: groupSet.has(group.group_id), selection: selection, disabled: disabled, onSelect: () => pick({ kind: 'group', id: group.group_id }), leading: _jsx(EntityAvatar, { icon: UsersIcon, label: group.name, size: "sm" }), label: group.name, suffix: tI18nComplete.raw('text24f15c9196e8') }, group.group_id)))] })) : null, filteredMembers.length > 0 ? (_jsxs(_Fragment, { children: [filteredGroups.length > 0 ? (_jsx(PickerSectionLabel, { children: tI18nComplete.raw('text1044a4c056d0') })) : null, filteredMembers.map((member) => {
262
+ !showEveryone ? (_jsx("p", { className: "text-muted-foreground px-3 py-6 text-center text-xs", children: tI18nComplete.raw('texte8dd87902b91') })) : (_jsxs(_Fragment, { children: [showEveryone && everyone ? (_jsx(PickerRow, { selected: value.everyone === true, selection: selection, disabled: disabled, onSelect: () => pick({ kind: 'everyone', id: scope.kind === 'project' ? scope.projectId : '' }), leading: _jsx(EntityAvatar, { icon: UsersThreeIcon, label: everyone.label, hint: everyone.label, size: "sm" }), label: everyone.label })) : null, inviteCandidate ? (_jsx(PickerRow, { selected: inviteSet.has(inviteCandidate), selection: selection, disabled: disabled, onSelect: () => pick({ kind: 'invite', id: inviteCandidate }), leading: _jsx("span", { className: "border-muted-foreground/40 text-muted-foreground flex size-6 shrink-0 items-center justify-center rounded-full border border-dashed", children: _jsx(UserPlusIcon, { className: "size-3.5" }) }), label: `Invite ${inviteCandidate}`, suffix: tI18nComplete.raw('text10d9e23d0185') })) : null, filteredGroups.length > 0 ? (_jsxs(_Fragment, { children: [_jsx(PickerSectionLabel, { children: tI18nComplete.raw('text39bbb719fa2b') }), filteredGroups.map((group) => (_jsx(PickerRow, { selected: groupSet.has(group.group_id), selection: selection, disabled: disabled, onSelect: () => pick({ kind: 'group', id: group.group_id }), leading: _jsx(EntityAvatar, { icon: UsersIcon, label: group.name, hint: group.name, size: "sm" }), label: group.name, suffix: tI18nComplete.raw('text24f15c9196e8') }, group.group_id)))] })) : null, filteredMembers.length > 0 ? (_jsxs(_Fragment, { children: [filteredGroups.length > 0 ? (_jsx(PickerSectionLabel, { children: tI18nComplete.raw('text1044a4c056d0') })) : null, filteredMembers.map((member) => {
262
263
  const label = principalLabel(member) || member.user_id;
263
- return (_jsx(PickerRow, { selected: memberSet.has(member.user_id), selection: selection, disabled: disabled, onSelect: () => pick({ kind: 'member', id: member.user_id }), leading: _jsx(UserAvatar, { email: label, size: "sm", variant: "primary" }), label: label, suffix: member.user_id === viewerId ? '(you)' : undefined }, member.user_id));
264
- })] })) : null, filteredAgents.length > 0 ? (_jsxs(_Fragment, { children: [_jsx(PickerSectionLabel, { children: tAgents('agentsSection') }), filteredAgents.map((agent) => (_jsx(PickerRow, { selected: agentSet.has(agent.service_account_id), selection: selection, disabled: disabled, onSelect: () => pick({ kind: 'agent', id: agent.service_account_id }), leading: _jsx(EntityAvatar, { icon: RobotIcon, label: agent.agent_name ?? '', size: "sm" }), label: agent.agent_name ?? agent.name, suffix: tAgents('agentBadge') }, agent.service_account_id)))] })) : null] })) })] }));
264
+ return (_jsx(PickerRow, { selected: memberSet.has(member.user_id), selection: selection, disabled: disabled, onSelect: () => pick({ kind: 'member', id: member.user_id }), leading: _jsx(UserAvatar, { email: label, hint: label, size: "sm", variant: "primary" }), label: label, suffix: member.user_id === viewerId ? '(you)' : undefined }, member.user_id));
265
+ })] })) : null, filteredAgents.length > 0 ? (_jsxs(_Fragment, { children: [_jsx(PickerSectionLabel, { children: tAgents('agentsSection') }), filteredAgents.map((agent) => (_jsx(PickerRow, { selected: agentSet.has(agent.service_account_id), selection: selection, disabled: disabled, onSelect: () => pick({ kind: 'agent', id: agent.service_account_id }), leading: _jsx(AgentMark, { slug: agent.agent_name ?? agent.name }), label: agent.agent_name ?? agent.name, suffix: tAgents('agentBadge') }, agent.service_account_id)))] })) : null] })) })] }));
265
266
  }
266
267
  function PickerSectionLabel({ children }) {
267
268
  return (_jsx("p", { className: "text-muted-foreground px-2 pt-2 pb-1 text-xs font-medium first:pt-1.5", children: children }));
268
269
  }
269
- function PickerRow({ selected, selection, disabled, onSelect, leading, label, suffix, }) {
270
- return (_jsxs("button", { type: "button", role: selection === 'single' ? 'radio' : undefined, "aria-checked": selection === 'single' ? selected : undefined, "aria-pressed": selection === 'multi' ? selected : undefined, disabled: disabled, onClick: onSelect, className: cn('flex w-full items-center gap-2.5 rounded-lg px-2 py-1.5 text-left transition-colors', 'disabled:cursor-not-allowed disabled:opacity-50', selected ? 'bg-primary/[0.06]' : 'hover:bg-muted/50'), children: [leading, _jsxs("span", { className: "text-foreground min-w-0 flex-1 truncate text-sm", children: [label, suffix ? _jsx("span", { className: "text-muted-foreground ml-1 text-xs", children: suffix }) : null] }), selected ? (_jsx("span", { className: "shrink-0 px-1", children: _jsx(CheckCircleIcon, { weight: "fill", className: "size-[1.1rem]" }) })) : null] }));
270
+ /** One picker row. Exported for the channel "Add members" picker, which moves `highlighted` with the arrow keys. */
271
+ export function PickerRow({ selected, selection, highlighted = false, disabled, onSelect, leading, label, suffix, }) {
272
+ return (_jsxs("button", { type: "button", role: selection === 'single' ? 'radio' : undefined, "aria-checked": selection === 'single' ? selected : undefined, "aria-pressed": selection === 'multi' ? selected : undefined, disabled: disabled, onClick: onSelect, className: cn('flex w-full items-center gap-2.5 rounded-lg px-2 py-1.5 text-left transition-colors', 'disabled:cursor-not-allowed disabled:opacity-50', selected ? 'bg-primary/[0.06]' : highlighted ? 'bg-muted/50' : 'hover:bg-muted/50'), children: [leading, _jsxs("span", { className: "text-foreground min-w-0 flex-1 truncate text-sm", children: [label, suffix ? _jsx("span", { className: "text-muted-foreground ml-1 text-xs", children: suffix }) : null] }), selected ? (_jsx("span", { className: "shrink-0 px-1", children: _jsx(CheckCircleIcon, { weight: "fill", className: "size-[1.1rem]" }) })) : null] }));
271
273
  }