@kortix/ui 0.14.8 → 0.14.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (567) hide show
  1. package/README.md +2 -2
  2. package/dist/_vendor/kortix-shared.js +116 -3
  3. package/dist/_vendor/shared/app-config.d.ts +175 -0
  4. package/dist/_vendor/shared/artifact-comments.d.ts +235 -0
  5. package/dist/_vendor/shared/channel-descriptors.d.ts +96 -0
  6. package/dist/_vendor/shared/channel-message.d.ts +45 -5
  7. package/dist/_vendor/shared/index.d.ts +2 -0
  8. package/dist/_vendor/shared/space-slug.d.ts +37 -0
  9. package/dist/access/access/access-detail-shell.js +1 -1
  10. package/dist/access/access/principal-picker.d.ts +11 -0
  11. package/dist/access/access/principal-picker.js +3 -2
  12. package/dist/apps/app-preview-pool.d.ts +7 -2
  13. package/dist/apps/app-preview-pool.js +30 -7
  14. package/dist/apps/app-shared.d.ts +22 -15
  15. package/dist/apps/app-shared.js +37 -19
  16. package/dist/apps/index.d.ts +2 -2
  17. package/dist/apps/index.js +2 -2
  18. package/dist/artifacts/artifact-frame.d.ts +16 -0
  19. package/dist/artifacts/artifact-frame.js +55 -0
  20. package/dist/artifacts/artifact-session.d.ts +18 -0
  21. package/dist/artifacts/artifact-session.js +101 -0
  22. package/dist/artifacts/frame-policy.d.ts +30 -0
  23. package/dist/artifacts/frame-policy.js +61 -0
  24. package/dist/artifacts/index.d.ts +3 -0
  25. package/dist/artifacts/index.js +5 -0
  26. package/dist/browser/sandbox-browser-chrome.d.ts +4 -1
  27. package/dist/browser/sandbox-browser-chrome.js +2 -2
  28. package/dist/customize/agents/agent-grant-pages.d.ts +5 -1
  29. package/dist/customize/agents/agent-grant-pages.js +30 -4
  30. package/dist/customize/agents/agent-page.js +3 -1
  31. package/dist/customize/agents/agent-policy-sets.d.ts +43 -0
  32. package/dist/customize/agents/agent-policy-sets.js +72 -0
  33. package/dist/customize/agents/agent-triggers-section.js +2 -1
  34. package/dist/customize/connectors/add-mcp/add-mcp-server-dialog.d.ts +6 -1
  35. package/dist/customize/connectors/add-mcp/add-mcp-server-dialog.js +10 -4
  36. package/dist/customize/connectors/agent-access.d.ts +35 -0
  37. package/dist/customize/connectors/agent-access.js +77 -0
  38. package/dist/customize/connectors/catalog/browse-sections.d.ts +2 -29
  39. package/dist/customize/connectors/catalog/browse-sections.js +7 -74
  40. package/dist/customize/connectors/catalog/catalog-entry.d.ts +18 -37
  41. package/dist/customize/connectors/catalog/catalog-entry.js +28 -40
  42. package/dist/customize/connectors/catalog/connector-browse.d.ts +3 -32
  43. package/dist/customize/connectors/catalog/connector-browse.js +19 -50
  44. package/dist/customize/connectors/catalog/use-catalog.d.ts +20 -59
  45. package/dist/customize/connectors/catalog/use-catalog.js +48 -175
  46. package/dist/customize/connectors/connector-identity.d.ts +9 -11
  47. package/dist/customize/connectors/connector-identity.js +13 -42
  48. package/dist/customize/connectors/connector-moves-banner.d.ts +2 -1
  49. package/dist/customize/connectors/connector-moves-banner.js +4 -6
  50. package/dist/customize/connectors/connector-routes.d.ts +21 -9
  51. package/dist/customize/connectors/connector-routes.js +29 -20
  52. package/dist/customize/connectors/connectors-page.js +53 -82
  53. package/dist/customize/connectors/detail/app-page.js +226 -98
  54. package/dist/customize/connectors/detail/computer-app-page.d.ts +16 -0
  55. package/dist/customize/connectors/detail/computer-app-page.js +39 -0
  56. package/dist/customize/connectors/detail/connector-accounts.js +3 -1
  57. package/dist/customize/connectors/detail/connector-advanced-tools.d.ts +4 -1
  58. package/dist/customize/connectors/detail/connector-advanced-tools.js +2 -2
  59. package/dist/customize/connectors/detail/connector-agents.d.ts +14 -0
  60. package/dist/customize/connectors/detail/connector-agents.js +69 -0
  61. package/dist/customize/connectors/detail/connector-detail-tabs.js +2 -1
  62. package/dist/customize/connectors/detail/connector-move-row.d.ts +8 -5
  63. package/dist/customize/connectors/detail/connector-move-row.js +23 -14
  64. package/dist/customize/connectors/detail/connector-page.d.ts +4 -1
  65. package/dist/customize/connectors/detail/connector-page.js +14 -10
  66. package/dist/customize/connectors/detail/connector-policy-sets.d.ts +28 -0
  67. package/dist/customize/connectors/detail/connector-policy-sets.js +203 -0
  68. package/dist/customize/connectors/detail/connector-settings.d.ts +4 -1
  69. package/dist/customize/connectors/detail/connector-settings.js +7 -3
  70. package/dist/customize/connectors/detail/connector-status.d.ts +19 -6
  71. package/dist/customize/connectors/detail/connector-status.js +34 -10
  72. package/dist/customize/connectors/detail/connector-tabs.d.ts +4 -1
  73. package/dist/customize/connectors/detail/connector-tabs.js +8 -2
  74. package/dist/customize/connectors/detail/connector-tools.d.ts +3 -3
  75. package/dist/customize/connectors/detail/connector-tools.js +105 -48
  76. package/dist/customize/connectors/detail/email-inboxes.d.ts +43 -0
  77. package/dist/customize/connectors/detail/email-inboxes.js +184 -0
  78. package/dist/customize/connectors/detail/provider-info.d.ts +1 -1
  79. package/dist/customize/connectors/detail/provider-info.js +2 -2
  80. package/dist/customize/connectors/detail/status-badge.d.ts +1 -1
  81. package/dist/customize/connectors/detail/status-badge.js +4 -5
  82. package/dist/customize/connectors/detail/use-connector-detail.d.ts +6 -0
  83. package/dist/customize/connectors/detail/use-connector-detail.js +14 -4
  84. package/dist/customize/connectors/install/install-dialog.d.ts +23 -0
  85. package/dist/customize/connectors/install/install-dialog.js +40 -0
  86. package/dist/customize/connectors/install/install.d.ts +13 -2
  87. package/dist/customize/connectors/install/install.js +9 -4
  88. package/dist/customize/connectors/install/use-install.d.ts +19 -2
  89. package/dist/customize/connectors/install/use-install.js +65 -37
  90. package/dist/customize/connectors/install/way-kind.d.ts +5 -0
  91. package/dist/customize/connectors/install/way-kind.js +16 -0
  92. package/dist/customize/connectors/provider-label.d.ts +2 -1
  93. package/dist/customize/connectors/provider-label.js +13 -3
  94. package/dist/customize/connectors/tools/pattern-rule-draft.d.ts +4 -0
  95. package/dist/customize/connectors/tools/pattern-rule-draft.js +12 -3
  96. package/dist/customize/connectors/tools/policy-sets.d.ts +27 -0
  97. package/dist/customize/connectors/tools/policy-sets.js +41 -0
  98. package/dist/customize/connectors/tools/tool-groups.d.ts +32 -9
  99. package/dist/customize/connectors/tools/tool-groups.js +78 -16
  100. package/dist/customize/connectors/tools/tool-policy-control.d.ts +11 -10
  101. package/dist/customize/connectors/tools/tool-policy-control.js +15 -16
  102. package/dist/customize/connectors/tools/tool-policy-labels.d.ts +6 -5
  103. package/dist/customize/connectors/tools/tool-policy-labels.js +17 -16
  104. package/dist/customize/connectors/tools/tool-policy.d.ts +50 -4
  105. package/dist/customize/connectors/tools/tool-policy.js +74 -8
  106. package/dist/customize/connectors/use-agent-access.d.ts +85 -0
  107. package/dist/customize/connectors/use-agent-access.js +72 -0
  108. package/dist/customize/migrate-to-v2/index.d.ts +1 -2
  109. package/dist/customize/migrate-to-v2/index.js +1 -2
  110. package/dist/customize/migrate-to-v2/migration-prompt.d.ts +12 -25
  111. package/dist/customize/migrate-to-v2/migration-prompt.js +34 -236
  112. package/dist/customize/migrate-to-v2/upgrade-defs.d.ts +1 -1
  113. package/dist/customize/migrate-to-v2/upgrade-defs.js +7 -6
  114. package/dist/customize/migrate-to-v2/upgrade-view.js +7 -7
  115. package/dist/customize/migrate-to-v2/use-run-upgrade.d.ts +3 -3
  116. package/dist/customize/providers/provider-accordion.js +17 -2
  117. package/dist/customize/sections/component/channel-access-panel.d.ts +16 -0
  118. package/dist/customize/sections/component/channel-access-panel.js +146 -0
  119. package/dist/customize/sections/component/channel-connect-hero.d.ts +3 -2
  120. package/dist/customize/sections/component/channel-connect-hero.js +3 -2
  121. package/dist/customize/sections/component/channel-hero-frame.d.ts +31 -0
  122. package/dist/customize/sections/component/channel-hero-frame.js +40 -0
  123. package/dist/customize/sections/component/channel-mocks.d.ts +6 -0
  124. package/dist/customize/sections/component/channel-mocks.js +46 -0
  125. package/dist/customize/sections/component/channel-row.d.ts +13 -3
  126. package/dist/customize/sections/component/channel-row.js +10 -4
  127. package/dist/customize/sections/component/email-connect-form.d.ts +27 -0
  128. package/dist/customize/sections/component/email-connect-form.js +183 -0
  129. package/dist/customize/sections/component/slack-connect-card.d.ts +7 -0
  130. package/dist/customize/sections/component/slack-connect-card.js +2 -3
  131. package/dist/customize/sections/component/teams-connect-card.d.ts +7 -0
  132. package/dist/customize/sections/component/teams-connect-card.js +2 -3
  133. package/dist/customize/sections/component/telegram-channel-row.js +21 -28
  134. package/dist/customize/sections/connectors-view.d.ts +1 -15
  135. package/dist/customize/sections/connectors-view.js +81 -314
  136. package/dist/customize/sections/view/agent-editor-catalog.js +10 -0
  137. package/dist/customize/sections/view/channels-view.d.ts +6 -1
  138. package/dist/customize/sections/view/channels-view.js +72 -81
  139. package/dist/customize/sections/view/gateway/gateway-overview.js +10 -2
  140. package/dist/customize/settings/rail.js +9 -0
  141. package/dist/customize/settings/settings-tabs.d.ts +1 -1
  142. package/dist/customize/settings/settings-tabs.js +1 -0
  143. package/dist/customize/settings/tabs/chrome-connections-tab.d.ts +6 -0
  144. package/dist/customize/settings/tabs/chrome-connections-tab.js +99 -0
  145. package/dist/customize/settings/tabs/experimental-tab.js +35 -16
  146. package/dist/customize/shared/catalog/catalog-empty-state.d.ts +4 -15
  147. package/dist/customize/shared/catalog/catalog-empty-state.js +9 -7
  148. package/dist/customize/shared/channels-switch-dialog.d.ts +18 -0
  149. package/dist/customize/shared/channels-switch-dialog.js +30 -0
  150. package/dist/customize/shared/feature-gate-screen.js +27 -9
  151. package/dist/customize/shared/use-customize-prefetch.d.ts +2 -3
  152. package/dist/customize/shared/use-customize-prefetch.js +9 -27
  153. package/dist/customize/triggers/schedule/post-to-field.d.ts +18 -0
  154. package/dist/customize/triggers/schedule/post-to-field.js +49 -0
  155. package/dist/customize/triggers/schedule/schedule-copy.d.ts +10 -6
  156. package/dist/customize/triggers/schedule/schedule-copy.js +42 -11
  157. package/dist/customize/triggers/schedule/schedule-detail-sheet.js +2 -1
  158. package/dist/customize/triggers/schedule/trigger-composer-logic.d.ts +22 -0
  159. package/dist/customize/triggers/schedule/trigger-composer-logic.js +25 -0
  160. package/dist/customize/triggers/schedule/trigger-composer.d.ts +5 -0
  161. package/dist/customize/triggers/schedule/trigger-composer.js +23 -14
  162. package/dist/customize/triggers/schedule/trigger-edit-logic.js +3 -0
  163. package/dist/customize/triggers/schedule/trigger-filter.js +1 -1
  164. package/dist/customize/triggers/schedule/trigger-runs-logic.d.ts +2 -2
  165. package/dist/customize/triggers/schedule/trigger-runs-panel.js +1 -0
  166. package/dist/customize/triggers/schedule/trigger-toast.js +2 -1
  167. package/dist/customize/triggers/schedule-view.js +5 -2
  168. package/dist/files/index.d.ts +1 -0
  169. package/dist/files/index.js +1 -0
  170. package/dist/files/project/change-request-recovery.d.ts +1 -26
  171. package/dist/files/project/change-request-recovery.js +1 -59
  172. package/dist/files/project/components/change-request-detail-dialog.js +13 -3
  173. package/dist/files/project/components/drive-explorer.js +15 -15
  174. package/dist/files/project/components/drive-toolbar.d.ts +16 -2
  175. package/dist/files/project/components/drive-toolbar.js +14 -5
  176. package/dist/files/project/hooks/use-change-request-recovery.js +3 -19
  177. package/dist/files/project/hooks/use-change-requests.d.ts +1 -0
  178. package/dist/files/project/hooks/use-change-requests.js +11 -2
  179. package/dist/files/renderers/image-frame.d.ts +48 -0
  180. package/dist/files/renderers/image-frame.js +59 -0
  181. package/dist/files/renderers/image-renderer.d.ts +11 -1
  182. package/dist/files/renderers/image-renderer.js +13 -3
  183. package/dist/files/renderers/pdf/pdf-clipboard.d.ts +2 -0
  184. package/dist/files/renderers/pdf/pdf-clipboard.js +21 -0
  185. package/dist/files/renderers/pdf/pdf-viewer.js +4 -2
  186. package/dist/files/renderers/show-content-renderer.d.ts +9 -1
  187. package/dist/files/renderers/show-content-renderer.js +56 -14
  188. package/dist/files/runtime/file-source.js +2 -0
  189. package/dist/files/runtime/hooks/use-binary-blob.d.ts +10 -1
  190. package/dist/files/runtime/hooks/use-binary-blob.js +10 -4
  191. package/dist/files/runtime/hooks/use-shared-image.d.ts +41 -0
  192. package/dist/files/runtime/hooks/use-shared-image.js +177 -0
  193. package/dist/files/viewer/file-content-renderer.d.ts +22 -1
  194. package/dist/files/viewer/file-content-renderer.js +50 -7
  195. package/dist/files/viewer/file-header.d.ts +7 -3
  196. package/dist/files/viewer/file-header.js +20 -11
  197. package/dist/files/viewer/file-preview-modal.d.ts +1 -1
  198. package/dist/files/viewer/file-preview-modal.js +10 -22
  199. package/dist/files/viewer/file-source.d.ts +13 -0
  200. package/dist/files/viewer/use-file-content-state.d.ts +2 -0
  201. package/dist/files/viewer/use-file-content-state.js +28 -10
  202. package/dist/files/viewer/viewer-actions.d.ts +3 -1
  203. package/dist/files/viewer/viewer-actions.js +2 -2
  204. package/dist/hooks/use-media-query.d.ts +1 -0
  205. package/dist/hooks/use-mobile.d.ts +5 -0
  206. package/dist/hooks/use-mobile.js +8 -0
  207. package/dist/i18n/en.d.ts +1062 -85
  208. package/dist/i18n/en.js +1078 -101
  209. package/dist/i18n/ui-catalog/localize-ui-catalog.js +4 -0
  210. package/dist/i18n/ui-catalog/remaining-ui-translation-keys.generated.js +15 -3
  211. package/dist/index.d.ts +2 -2
  212. package/dist/index.js +2 -2
  213. package/dist/internal/account-hub/account-settings-sidebar.js +1 -1
  214. package/dist/internal/account-hub/hub-sheet.d.ts +9 -1
  215. package/dist/internal/account-hub/hub-sheet.js +21 -5
  216. package/dist/internal/account-hub/sections.d.ts +1 -1
  217. package/dist/internal/account-hub/sections.js +2 -1
  218. package/dist/internal/apps-and-extensions/apps-modal.d.ts +9 -0
  219. package/dist/internal/apps-and-extensions/apps-modal.js +107 -0
  220. package/dist/internal/auth/auth-card-shell.js +3 -3
  221. package/dist/internal/chrome/browser-icon.d.ts +24 -0
  222. package/dist/internal/chrome/browser-icon.js +58 -0
  223. package/dist/internal/chrome/chrome-card-state.d.ts +16 -0
  224. package/dist/internal/chrome/chrome-card-state.js +9 -0
  225. package/dist/internal/chrome/chrome-connect.d.ts +69 -0
  226. package/dist/internal/chrome/chrome-connect.js +178 -0
  227. package/dist/internal/chrome/chrome-mock.d.ts +4 -0
  228. package/dist/internal/chrome/chrome-mock.js +15 -0
  229. package/dist/internal/chrome/chrome-names.d.ts +15 -0
  230. package/dist/internal/chrome/chrome-names.js +35 -0
  231. package/dist/internal/chrome/extension.d.ts +47 -0
  232. package/dist/internal/chrome/extension.js +91 -0
  233. package/dist/internal/chrome/use-chrome-offered.d.ts +11 -0
  234. package/dist/internal/chrome/use-chrome-offered.js +22 -0
  235. package/dist/internal/components/agent-mark.js +5 -2
  236. package/dist/internal/connector-logo/connector-logo-source.d.ts +64 -0
  237. package/dist/internal/connector-logo/connector-logo-source.js +49 -0
  238. package/dist/internal/connector-logo/connector-logo.d.ts +39 -0
  239. package/dist/internal/connector-logo/connector-logo.js +56 -0
  240. package/dist/internal/connector-logo/connector-mark-files.d.ts +11 -0
  241. package/dist/internal/connector-logo/connector-mark-files.js +35 -0
  242. package/dist/internal/files/file-read-retry.d.ts +13 -0
  243. package/dist/internal/files/file-read-retry.js +23 -3
  244. package/dist/internal/files/session-drive-files.d.ts +5 -1
  245. package/dist/internal/files/session-drive-files.js +7 -2
  246. package/dist/internal/hooks/channels/use-channels-installations.d.ts +32 -5
  247. package/dist/internal/hooks/channels/use-channels-installations.js +55 -7
  248. package/dist/internal/hooks/channels/use-email-inboxes.d.ts +19 -0
  249. package/dist/internal/hooks/channels/use-email-inboxes.js +48 -0
  250. package/dist/internal/hooks/connectors/use-add-account.js +1 -1
  251. package/dist/internal/hooks/index.d.ts +1 -1
  252. package/dist/internal/hooks/index.js +1 -1
  253. package/dist/internal/hooks/projects/use-new-project-session.d.ts +9 -0
  254. package/dist/internal/hooks/projects/use-new-project-session.js +28 -12
  255. package/dist/internal/hooks/use-auto-scroll.d.ts +8 -1
  256. package/dist/internal/hooks/use-auto-scroll.js +4 -4
  257. package/dist/internal/icons/edge.d.ts +5 -0
  258. package/dist/internal/icons/edge.js +10 -0
  259. package/dist/internal/icons/telegram.d.ts +5 -0
  260. package/dist/internal/icons/telegram.js +6 -1
  261. package/dist/internal/layout/nav-hover-card.d.ts +35 -0
  262. package/dist/internal/layout/nav-hover-card.js +84 -0
  263. package/dist/internal/layout/project-nav-row.d.ts +3 -1
  264. package/dist/internal/layout/project-nav-row.js +3 -2
  265. package/dist/internal/layout/project-page-header.d.ts +4 -2
  266. package/dist/internal/layout/project-page-header.js +4 -3
  267. package/dist/internal/layout/project-settings-nav.js +59 -2
  268. package/dist/internal/lib/browser-error-noise.d.ts +1 -1
  269. package/dist/internal/lib/browser-error-noise.js +1 -1
  270. package/dist/internal/lib/browser-noise/rules/extensions.js +17 -3
  271. package/dist/internal/lib/browser-noise/rules/injected-scripts.d.ts +7 -0
  272. package/dist/internal/lib/browser-noise/rules/injected-scripts.js +15 -0
  273. package/dist/internal/lib/detect-os.d.ts +43 -0
  274. package/dist/internal/lib/detect-os.js +70 -0
  275. package/dist/internal/lib/manifest-version.d.ts +1 -1
  276. package/dist/internal/lib/manifest-version.js +2 -2
  277. package/dist/internal/lib/memory-href.d.ts +16 -0
  278. package/dist/internal/lib/memory-href.js +46 -0
  279. package/dist/internal/lib/use-project-feature-flags.js +13 -9
  280. package/dist/internal/lib/utils/heic-convert.d.ts +1 -1
  281. package/dist/internal/lib/utils/heic-convert.js +3 -4
  282. package/dist/internal/lib/web-notifications.d.ts +20 -0
  283. package/dist/internal/lib/web-notifications.js +48 -4
  284. package/dist/internal/notifications/notification-bell.d.ts +4 -1
  285. package/dist/internal/notifications/notification-bell.js +2 -2
  286. package/dist/internal/selection/selection-bar.d.ts +2 -1
  287. package/dist/internal/selection/selection-bar.js +1 -1
  288. package/dist/internal/stores/apps-modal-store.d.ts +8 -0
  289. package/dist/internal/stores/apps-modal-store.js +6 -0
  290. package/dist/internal/stores/composer-prefill-store.d.ts +12 -5
  291. package/dist/internal/stores/file-preview-store.d.ts +29 -2
  292. package/dist/internal/stores/file-preview-store.js +19 -1
  293. package/dist/internal/stores/kortix-computer-store.js +3 -0
  294. package/dist/internal/stores/sidebar-nav-store.d.ts +1 -1
  295. package/dist/internal/stores/sidebar-nav-store.js +3 -1
  296. package/dist/lib/routes.d.ts +13 -1
  297. package/dist/lib/routes.js +13 -0
  298. package/dist/markdown/index.d.ts +2 -1
  299. package/dist/markdown/index.js +2 -1
  300. package/dist/markdown/setup-links/approval-decision.d.ts +1 -0
  301. package/dist/markdown/setup-links/approval-decision.js +9 -3
  302. package/dist/markdown/setup-links/connector-handshake.d.ts +3 -1
  303. package/dist/markdown/setup-links/connector-handshake.js +12 -10
  304. package/dist/markdown/setup-links/secret-intake-form.d.ts +0 -10
  305. package/dist/markdown/setup-links/secret-intake-form.js +1 -1
  306. package/dist/markdown/setup-links/show-connect-hero.d.ts +28 -0
  307. package/dist/markdown/setup-links/show-connect-hero.js +91 -0
  308. package/dist/markdown/unified-markdown.js +5 -5
  309. package/dist/primitives/badge.d.ts +1 -1
  310. package/dist/primitives/badge.js +2 -0
  311. package/dist/primitives/disclosure.js +14 -2
  312. package/dist/primitives/empty-art.d.ts +12 -0
  313. package/dist/primitives/empty-art.js +11 -0
  314. package/dist/primitives/empty-state.d.ts +2 -2
  315. package/dist/primitives/empty-state.js +6 -5
  316. package/dist/primitives/mermaid-renderer.d.ts +2 -0
  317. package/dist/primitives/mermaid-renderer.js +21 -15
  318. package/dist/primitives/resizable.js +6 -1
  319. package/dist/primitives/resize-seam.d.ts +11 -0
  320. package/dist/primitives/resize-seam.js +12 -0
  321. package/dist/primitives/sidebar-panel.js +4 -7
  322. package/dist/primitives/tabs.d.ts +14 -1
  323. package/dist/primitives/tabs.js +1 -1
  324. package/dist/providers/ui-provider.d.ts +9 -0
  325. package/dist/session/composer/ComposerAboveCard.d.ts +1 -1
  326. package/dist/session/composer/ComposerAboveCard.js +2 -2
  327. package/dist/session/composer/ComposerCard.d.ts +1 -1
  328. package/dist/session/composer/ComposerCard.js +3 -3
  329. package/dist/session/composer/agent-selector.d.ts +13 -1
  330. package/dist/session/composer/agent-selector.js +25 -5
  331. package/dist/session/composer/composer-agent-access.d.ts +15 -0
  332. package/dist/session/composer/composer-agent-access.js +27 -0
  333. package/dist/session/composer/composer-chat-input.d.ts +8 -2
  334. package/dist/session/composer/composer-chat-input.js +8 -6
  335. package/dist/session/composer/composer-logic.d.ts +16 -0
  336. package/dist/session/composer/composer-logic.js +12 -0
  337. package/dist/session/composer/composer-underbar.d.ts +3 -1
  338. package/dist/session/composer/composer-underbar.js +4 -3
  339. package/dist/session/composer/composer.d.ts +15 -1
  340. package/dist/session/composer/composer.js +19 -1
  341. package/dist/session/composer/draft/composer-draft.d.ts +6 -2
  342. package/dist/session/composer/draft/composer-draft.js +5 -1
  343. package/dist/session/composer/reasoning-effort-selector.js +1 -1
  344. package/dist/session/models/chatgpt-connection-button.d.ts +11 -0
  345. package/dist/session/models/chatgpt-connection-button.js +54 -0
  346. package/dist/session/models/model-selector.js +5 -2
  347. package/dist/session/models/use-model-connection-gate.d.ts +5 -5
  348. package/dist/session/models/use-model-connection-gate.js +5 -5
  349. package/dist/session/outcomes/jump-to-outcome.d.ts +10 -0
  350. package/dist/session/outcomes/jump-to-outcome.js +11 -0
  351. package/dist/session/outcomes/session-outcomes-bridge.d.ts +14 -0
  352. package/dist/session/outcomes/session-outcomes-bridge.js +12 -0
  353. package/dist/session/outcomes/session-outcomes-provider.d.ts +3 -1
  354. package/dist/session/outcomes/session-outcomes-provider.js +33 -3
  355. package/dist/session/panel/easy/app-preview.d.ts +10 -0
  356. package/dist/session/panel/easy/app-preview.js +31 -12
  357. package/dist/session/panel/easy/change-requests-card.d.ts +7 -0
  358. package/dist/session/panel/easy/change-requests-card.js +17 -0
  359. package/dist/session/panel/easy/easy-panel-logic.js +7 -1
  360. package/dist/session/panel/easy/easy-panel.js +5 -2
  361. package/dist/session/panel/easy/file-preview.js +1 -1
  362. package/dist/session/panel/easy/outputs-card.d.ts +2 -1
  363. package/dist/session/panel/easy/outputs-card.js +3 -2
  364. package/dist/session/panel/mobile-tool-drawer.js +7 -1
  365. package/dist/session/panel/session-audit-panel.js +9 -2
  366. package/dist/session/panel/session-audit-shared.js +3 -1
  367. package/dist/session/panel/session-detail-panel.js +9 -3
  368. package/dist/session/panel/session-files-explorer.d.ts +9 -0
  369. package/dist/session/panel/session-files-explorer.js +12 -3
  370. package/dist/session/panel/session-panel-provider.d.ts +15 -1
  371. package/dist/session/panel/session-panel-provider.js +32 -7
  372. package/dist/session/panel/shared/derive-panels.d.ts +8 -1
  373. package/dist/session/panel/shared/derive-panels.js +12 -2
  374. package/dist/session/panel/shared/output-priority.js +2 -0
  375. package/dist/session/participants/session-participants.d.ts +8 -2
  376. package/dist/session/participants/session-participants.js +11 -4
  377. package/dist/session/prompts/approval-request.d.ts +5 -0
  378. package/dist/session/prompts/approval-request.js +9 -1
  379. package/dist/session/prompts/session-approval-review.d.ts +9 -0
  380. package/dist/session/prompts/session-approval-review.js +18 -0
  381. package/dist/session/status/session-error-banner.js +2 -49
  382. package/dist/session/status/session-starting-loader.d.ts +14 -2
  383. package/dist/session/status/session-starting-loader.js +16 -4
  384. package/dist/session/thread/after-first-prompt.d.ts +7 -0
  385. package/dist/session/thread/after-first-prompt.js +8 -0
  386. package/dist/session/thread/detect-command.d.ts +12 -0
  387. package/dist/session/thread/detect-command.js +20 -0
  388. package/dist/session/thread/session-chat.d.ts +3 -1
  389. package/dist/session/thread/session-chat.js +377 -252
  390. package/dist/session/thread/session-thread.d.ts +15 -1
  391. package/dist/session/thread/session-thread.js +20 -3
  392. package/dist/session/thread/session-transcript-class.d.ts +5 -1
  393. package/dist/session/thread/session-transcript-class.js +5 -1
  394. package/dist/session/thread/thread-boot-rows.d.ts +36 -0
  395. package/dist/session/thread/thread-boot-rows.js +89 -0
  396. package/dist/session/thread/transcript-rows.d.ts +31 -0
  397. package/dist/session/thread/transcript-rows.js +3 -0
  398. package/dist/session/thread/transcript.d.ts +0 -9
  399. package/dist/session/thread/transcript.js +104 -19
  400. package/dist/session/tool/shared/infrastructure-contexts.d.ts +28 -0
  401. package/dist/session/tool/shared/infrastructure-contexts.js +31 -3
  402. package/dist/session/tool/tool-part-renderer.d.ts +5 -4
  403. package/dist/session/tool/tool-part-renderer.js +8 -3
  404. package/dist/session/tool/tools/bash-tool.js +7 -6
  405. package/dist/session/tool/tools/channel-send-card.d.ts +1 -2
  406. package/dist/session/tool/tools/channel-send.d.ts +2 -1
  407. package/dist/session/tool/tools/codemode-tool.js +1 -1
  408. package/dist/session/tool/tools/connector-tools.js +1 -1
  409. package/dist/session/tool/tools/image-gen-tool.d.ts +1 -1
  410. package/dist/session/tool/tools/image-gen-tool.js +241 -53
  411. package/dist/session/tool/tools/show-tool.js +19 -8
  412. package/dist/session/turn/channel-brand.d.ts +8 -3
  413. package/dist/session/turn/channel-brand.js +20 -4
  414. package/dist/session/turn/message-author.d.ts +8 -0
  415. package/dist/session/turn/message-author.js +24 -0
  416. package/dist/session/turn/message-row.d.ts +52 -0
  417. package/dist/session/turn/message-row.js +44 -0
  418. package/dist/session/turn/plan-anchor.d.ts +1 -1
  419. package/dist/session/turn/plan-anchor.js +1 -1
  420. package/dist/session/turn/user-message.d.ts +14 -6
  421. package/dist/session/turn/user-message.js +35 -15
  422. package/dist/styles.css +1 -1
  423. package/dist/workspace/home/access-requests-bell.d.ts +9 -2
  424. package/dist/workspace/home/access-requests-bell.js +20 -6
  425. package/dist/workspace/home/first-chat.d.ts +8 -21
  426. package/dist/workspace/home/first-chat.js +22 -72
  427. package/dist/workspace/index.d.ts +6 -0
  428. package/dist/workspace/index.js +6 -0
  429. package/dist/workspace/layout/project-home.d.ts +14 -2
  430. package/dist/workspace/layout/project-home.js +60 -21
  431. package/dist/workspace/layout/use-project-home-send.d.ts +9 -1
  432. package/dist/workspace/layout/use-project-home-send.js +82 -3
  433. package/dist/workspace/memory/body-doc.d.ts +17 -0
  434. package/dist/workspace/memory/body-doc.js +208 -0
  435. package/dist/workspace/memory/body-extensions.d.ts +38 -0
  436. package/dist/workspace/memory/body-extensions.js +103 -0
  437. package/dist/workspace/memory/company-memory-page.d.ts +8 -0
  438. package/dist/workspace/memory/company-memory-page.js +16 -0
  439. package/dist/workspace/memory/memory-all.d.ts +20 -0
  440. package/dist/workspace/memory/memory-all.js +27 -0
  441. package/dist/workspace/memory/memory-body.d.ts +19 -0
  442. package/dist/workspace/memory/memory-body.js +139 -0
  443. package/dist/workspace/memory/memory-empty.d.ts +13 -0
  444. package/dist/workspace/memory/memory-empty.js +28 -0
  445. package/dist/workspace/memory/memory-history.d.ts +27 -0
  446. package/dist/workspace/memory/memory-history.js +108 -0
  447. package/dist/workspace/memory/memory-labels.d.ts +16 -0
  448. package/dist/workspace/memory/memory-labels.js +47 -0
  449. package/dist/workspace/memory/memory-page-list.d.ts +34 -0
  450. package/dist/workspace/memory/memory-page-list.js +156 -0
  451. package/dist/workspace/memory/memory-reader.d.ts +58 -0
  452. package/dist/workspace/memory/memory-reader.js +123 -0
  453. package/dist/workspace/memory/memory-view.d.ts +21 -0
  454. package/dist/workspace/memory/memory-view.js +124 -0
  455. package/dist/workspace/memory/remember-popover.d.ts +19 -0
  456. package/dist/workspace/memory/remember-popover.js +61 -0
  457. package/dist/workspace/memory/remember-this.d.ts +12 -0
  458. package/dist/workspace/memory/remember-this.js +89 -0
  459. package/dist/workspace/memory/source-mark.d.ts +18 -0
  460. package/dist/workspace/memory/source-mark.js +79 -0
  461. package/dist/workspace/memory/used-memory-chip.d.ts +14 -0
  462. package/dist/workspace/memory/used-memory-chip.js +61 -0
  463. package/dist/workspace/new/advanced-fields.d.ts +2 -1
  464. package/dist/workspace/new/advanced-fields.js +2 -2
  465. package/dist/workspace/new/source-param.d.ts +1 -1
  466. package/dist/workspace/new/source-param.js +3 -1
  467. package/dist/workspace/new/use-create-workspace.d.ts +8 -10
  468. package/dist/workspace/new/use-create-workspace.js +3 -3
  469. package/dist/workspace/projects/onboarding/app-logo.d.ts +7 -2
  470. package/dist/workspace/projects/onboarding/app-logo.js +6 -13
  471. package/dist/workspace/projects/policies-panel.js +5 -3
  472. package/dist/workspace/review/review-actions.d.ts +4 -2
  473. package/dist/workspace/review/review-actions.js +8 -2
  474. package/dist/workspace/review/review-center.js +11 -7
  475. package/dist/workspace/review/review-detail.d.ts +10 -0
  476. package/dist/workspace/review/review-detail.js +101 -13
  477. package/dist/workspace/saved-session-skeleton.d.ts +2 -2
  478. package/dist/workspace/saved-session-skeleton.js +3 -3
  479. package/dist/workspace/session-workspace.js +15 -13
  480. package/dist/workspace/sessions/project-sessions-view.js +3 -2
  481. package/dist/workspace/sessions/session-label-badges.js +2 -1
  482. package/dist/workspace/sessions/sessions-toolbar.d.ts +3 -1
  483. package/dist/workspace/sessions/sessions-toolbar.js +2 -2
  484. package/dist/workspace/sidebar/footer/project-apps-nav.d.ts +5 -0
  485. package/dist/workspace/sidebar/footer/project-apps-nav.js +41 -2
  486. package/dist/workspace/sidebar/footer/project-artifacts-nav.d.ts +6 -0
  487. package/dist/workspace/sidebar/footer/project-artifacts-nav.js +22 -0
  488. package/dist/workspace/sidebar/footer/project-chrome-nav.d.ts +10 -0
  489. package/dist/workspace/sidebar/footer/project-chrome-nav.js +56 -0
  490. package/dist/workspace/sidebar/footer/project-manifest-upgrade-alert.js +13 -13
  491. package/dist/workspace/sidebar/footer/project-memory-nav.d.ts +7 -0
  492. package/dist/workspace/sidebar/footer/project-memory-nav.js +19 -0
  493. package/dist/workspace/sidebar/nav-row-meta.js +14 -2
  494. package/dist/workspace/sidebar/project-nav-items.js +3 -0
  495. package/dist/workspace/sidebar/project-session-list.js +68 -56
  496. package/dist/workspace/sidebar/project-sidebar.js +13 -2
  497. package/dist/workspace/sidebar/project-spaces-nav.d.ts +8 -0
  498. package/dist/workspace/sidebar/project-spaces-nav.js +69 -0
  499. package/dist/workspace/sidebar/session-group-order.d.ts +9 -0
  500. package/dist/workspace/sidebar/session-group-order.js +25 -0
  501. package/dist/workspace/sidebar/session-group-sections.d.ts +62 -0
  502. package/dist/workspace/sidebar/session-group-sections.js +267 -0
  503. package/dist/workspace/sidebar/session-list-chrome.d.ts +28 -0
  504. package/dist/workspace/sidebar/session-list-chrome.js +50 -0
  505. package/dist/workspace/spaces/channel-glyph.d.ts +5 -0
  506. package/dist/workspace/spaces/channel-glyph.js +6 -0
  507. package/dist/workspace/spaces/channel-setup.d.ts +16 -0
  508. package/dist/workspace/spaces/channel-setup.js +105 -0
  509. package/dist/workspace/spaces/channels-onboarding.d.ts +13 -0
  510. package/dist/workspace/spaces/channels-onboarding.js +37 -0
  511. package/dist/workspace/spaces/create-channel-dialog.d.ts +16 -0
  512. package/dist/workspace/spaces/create-channel-dialog.js +158 -0
  513. package/dist/workspace/spaces/private-channels-not-in.d.ts +9 -0
  514. package/dist/workspace/spaces/private-channels-not-in.js +69 -0
  515. package/dist/workspace/spaces/space-agents.d.ts +10 -0
  516. package/dist/workspace/spaces/space-agents.js +10 -0
  517. package/dist/workspace/spaces/space-details-dialog.d.ts +20 -0
  518. package/dist/workspace/spaces/space-details-dialog.js +176 -0
  519. package/dist/workspace/spaces/space-link-label.d.ts +49 -0
  520. package/dist/workspace/spaces/space-link-label.js +73 -0
  521. package/dist/workspace/spaces/space-links.d.ts +19 -0
  522. package/dist/workspace/spaces/space-links.js +230 -0
  523. package/dist/workspace/spaces/space-members.d.ts +46 -0
  524. package/dist/workspace/spaces/space-members.js +182 -0
  525. package/dist/workspace/spaces/space-roster.d.ts +15 -0
  526. package/dist/workspace/spaces/space-roster.js +44 -0
  527. package/dist/workspace/spaces/space-threads-tab.d.ts +56 -0
  528. package/dist/workspace/spaces/space-threads-tab.js +156 -0
  529. package/dist/workspace/spaces/space-timeline-view.d.ts +254 -0
  530. package/dist/workspace/spaces/space-timeline-view.js +235 -0
  531. package/dist/workspace/spaces/space-timeline.d.ts +106 -0
  532. package/dist/workspace/spaces/space-timeline.js +183 -0
  533. package/dist/workspace/spaces/space-triggers.d.ts +13 -0
  534. package/dist/workspace/spaces/space-triggers.js +78 -0
  535. package/dist/workspace/spaces/space-view.d.ts +37 -0
  536. package/dist/workspace/spaces/space-view.js +436 -0
  537. package/package.json +67 -36
  538. package/skills/kortix-ui/SKILL.md +3 -3
  539. package/skills/kortix-ui/references/custom-dashboard.md +3 -3
  540. package/skills/kortix-ui/references/modules.md +29 -5
  541. package/skills/kortix-ui/references/theming.md +1 -1
  542. package/dist/customize/connectors/catalog/merge-search.d.ts +0 -10
  543. package/dist/customize/connectors/catalog/merge-search.js +0 -26
  544. package/dist/customize/connectors/detail/find-easy-connect-app.d.ts +0 -29
  545. package/dist/customize/connectors/detail/find-easy-connect-app.js +0 -22
  546. package/dist/customize/migrate-to-v2/use-migrate-to-v2.d.ts +0 -9
  547. package/dist/customize/migrate-to-v2/use-migrate-to-v2.js +0 -24
  548. package/dist/customize/sections/connector-connection-header.d.ts +0 -36
  549. package/dist/customize/sections/connector-connection-header.js +0 -33
  550. package/dist/customize/sections/connector-connection-modal.d.ts +0 -34
  551. package/dist/customize/sections/connector-connection-modal.js +0 -72
  552. package/dist/customize/sections/discover-catalogue-card.d.ts +0 -19
  553. package/dist/customize/sections/discover-catalogue-card.js +0 -26
  554. package/dist/customize/sections/discover-catalogue-detail.d.ts +0 -15
  555. package/dist/customize/sections/discover-catalogue-detail.js +0 -24
  556. package/dist/customize/sections/discover-catalogue.d.ts +0 -17
  557. package/dist/customize/sections/discover-catalogue.js +0 -132
  558. package/dist/customize/sections/llm-provider/provider-access-menu.d.ts +0 -10
  559. package/dist/customize/sections/llm-provider/provider-access-menu.js +0 -23
  560. package/dist/files/project/components/drive-empty-art.d.ts +0 -2
  561. package/dist/files/project/components/drive-empty-art.js +0 -5
  562. package/dist/internal/hooks/use-media-query.d.ts +0 -2
  563. package/dist/internal/share/public-share-link-button.d.ts +0 -14
  564. package/dist/internal/share/public-share-link-button.js +0 -17
  565. package/dist/markdown/setup-links/app-credentials-form.d.ts +0 -12
  566. package/dist/markdown/setup-links/app-credentials-form.js +0 -115
  567. /package/dist/{internal/hooks → hooks}/use-media-query.js +0 -0
@@ -0,0 +1,54 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useTranslations } from '../../i18n/index.js';
4
+ import { Button } from '../../primitives/button.js';
5
+ import { cn } from '../../lib/utils.js';
6
+ import { useSessionIds } from '../../providers/session-ids.js';
7
+ import { useUiComponents, useUiViewerId } from '../../providers/ui-provider.js';
8
+ import { useFeatureFlag, useModelAccess, useProjectSession, useSessionProviderSecretPools, } from '@kortix/sdk/react';
9
+ import { useState } from 'react';
10
+ import { chatGptActionApplies } from './chatgpt-connection-action.js';
11
+ import { sessionPersonalUser } from '../overrides/provider-pool-draft.js';
12
+ /**
13
+ * The ChatGPT fix for a failed turn or tool call (the session error row, the
14
+ * image card). It needs the session the call belongs to, so it renders only on
15
+ * a session route; elsewhere the row stays informational.
16
+ */
17
+ export function ChatGptConnectionSlot({ action, className = 'mt-2 pl-7', }) {
18
+ const ids = useSessionIds();
19
+ const projectId = ids.projectId ?? null;
20
+ const sessionId = ids.sessionId ?? null;
21
+ if (!projectId || !sessionId)
22
+ return null;
23
+ return _jsx(ChatGptConnectionButton, { action: action, projectId: projectId, sessionId: sessionId, className: className });
24
+ }
25
+ /**
26
+ * Opens the ChatGPT accounts dialog, which exists only with pooled provider
27
+ * secrets and the LLM gateway on. Shown only where connecting or
28
+ * reconnecting an account can fix this session (`chatGptActionApplies`).
29
+ */
30
+ function ChatGptConnectionButton({ action, projectId, sessionId, className, }) {
31
+ const t = useTranslations('pooledSecrets');
32
+ const viewerId = useUiViewerId();
33
+ const pooled = useFeatureFlag(projectId, 'pooled_provider_secrets');
34
+ const enabled = pooled.enabled;
35
+ const access = useModelAccess(enabled ? projectId : null);
36
+ const session = useProjectSession(projectId, sessionId, { enabled });
37
+ const pools = useSessionProviderSecretPools(enabled ? projectId : null, sessionId);
38
+ const [open, setOpen] = useState(false);
39
+ const { ProviderAccountsModal } = useUiComponents();
40
+ const applies = !!ProviderAccountsModal &&
41
+ enabled &&
42
+ !(access.data?.disabledProviders ?? []).includes('codex') &&
43
+ chatGptActionApplies({
44
+ action,
45
+ personalUser: sessionPersonalUser(session.data),
46
+ viewerId: viewerId,
47
+ explicitSelection: pools.isSuccess
48
+ ? pools.data.pools.some((pool) => pool.provider_id === 'codex')
49
+ : undefined,
50
+ });
51
+ if (!applies || !ProviderAccountsModal)
52
+ return null;
53
+ return (_jsxs("div", { className: cn(className), children: [_jsx(Button, { size: "sm", className: "active:scale-[0.96]", onClick: () => setOpen(true), children: t(action === 'reconnect' ? 'reconnectChatGpt' : 'connectChatGpt') }), _jsx(ProviderAccountsModal, { projectId: projectId, providerId: "codex", open: open, onOpenChange: setOpen })] }));
54
+ }
@@ -106,7 +106,7 @@ function ModelRow({ model, groupProviderID, groupProviderName, isSelected, isAcc
106
106
  providerID: model.providerID,
107
107
  modelID: model.modelID,
108
108
  });
109
- }, className: cn('absolute inset-0 flex cursor-pointer items-center justify-center rounded-md', 'text-muted-foreground/70 hover:text-foreground hover:bg-foreground/10',
109
+ }, className: cn('absolute inset-0 flex cursor-pointer items-center justify-center rounded-md', 'text-muted-foreground hover:text-foreground hover:bg-foreground/10',
110
110
  /* `opacity` is NOT in this list, on purpose — see above. These
111
111
  only ever run on the one row the cursor is on, so they cannot
112
112
  leave a trail. */
@@ -304,7 +304,10 @@ export function ModelSelector({ models, selectedModel, onSelect, defaultControls
304
304
  setOpen(false);
305
305
  openUpgrade();
306
306
  }, [openUpgrade, setOpen]);
307
- return (_jsxs(_Fragment, { children: [connectionModal, projectId && chatGptPossible && ProviderAccountsModal && (_jsx(ProviderAccountsModal, { projectId: projectId, providerId: "codex", open: chatGptOpen, onOpenChange: setChatGptOpen })), _jsxs(CommandPopover, { open: disabled ? false : open, onOpenChange: (next) => !disabled && setOpen(next), children: [_jsx(CommandPopoverTrigger, { children: appearance === 'field' ? (_jsxs("button", { type: "button", disabled: disabled, className: cn(triggerVariants(), 'h-9 w-full'), children: [_jsx("span", { className: "truncate", children: displayName }), disabled ? null : _jsx(ChevronDown, { className: cn(TRIGGER_CARET_CLASS, 'size-4') })] })) : (_jsxs(Button, { type: "button", variant: triggerVariant, size: "sm", className: cn('rounded-lg hit-area-y-3', triggerVariant === 'ghost' && 'text-muted-foreground'), children: [_jsx("span", { className: cn('max-w-30 truncate', triggerLabelClassName), children: displayName }), _jsx(ChevronDown, { className: cn('duration-moderate size-3 transition-transform ease-out', open && 'rotate-180') })] })) }), _jsx(CommandPopoverContent, { side: "top", align: "start", sideOffset: 8, className: "w-[min(300px,calc(100vw-1.5rem))]", children: _jsxs(_Fragment, { children: [_jsx(CommandInput, { compact: true, placeholder: tModel('search'), value: search, onValueChange: setSearch, rightElement: canManageModels && canConnectProvider ? (_jsxs("div", { className: "-mr-0.5 flex shrink-0 items-center gap-0.5", children: [_jsx(Hint, { label: tModel('connectProvider'), side: "top", className: "z-50", children: _jsx("button", { type: "button", "aria-label": tModel('addProvider'), onClick: () => handleOpenProviderModal('providers'), className: "text-muted-foreground hover:text-foreground hover:bg-muted flex size-8 cursor-pointer items-center justify-center rounded-md transition-colors", children: _jsx(Plus, { className: "size-4" }) }) }), _jsx(Hint, { label: tModel('manageModels'), side: "top", className: "z-50", children: _jsx("button", { type: "button", "aria-label": tModel('manageModels'), onClick: () => handleOpenProviderModal('models'), className: "text-muted-foreground hover:text-foreground hover:bg-muted flex size-8 cursor-pointer items-center justify-center rounded-md transition-colors", children: _jsx(SlidersHorizontal, { className: "size-4" }) }) })] })) : undefined }), grouped.length > 1 && _jsx(CommandSeparator, { className: "bg-border/60" }), _jsx(CommandList, { className: "max-h-[380px]", children: modelsLoading || entitlementsPending ? (_jsx("div", { className: "flex min-h-32 items-center justify-center", role: "status", "aria-label": tModel('loading'), children: _jsx(Loading, { className: "text-muted-foreground size-4 shrink-0" }) })) : grouped.length > 0 ? (_jsxs(_Fragment, { children: [pinnedDefault && (_jsxs(_Fragment, { children: [_jsx(CommandGroup, { heading: _jsx(GroupHeading, { children: tModel('yourDefault') }), forceMount: true, children: _jsx(ModelRow, { model: pinnedDefault.model, groupProviderID: pinnedDefault.providerID, groupProviderName: pinnedDefault.providerName, isSelected: availableSelectedModel?.providerID === pinnedDefault.model.providerID &&
307
+ return (_jsxs(_Fragment, { children: [connectionModal, projectId && chatGptPossible && ProviderAccountsModal && (_jsx(ProviderAccountsModal, { projectId: projectId, providerId: "codex", open: chatGptOpen, onOpenChange: setChatGptOpen })), _jsxs(CommandPopover, { open: disabled ? false : open, onOpenChange: (next) => !disabled && setOpen(next), children: [_jsx(CommandPopoverTrigger, { children: appearance === 'field' ? (_jsxs("button", { type: "button", disabled: disabled, className: cn(triggerVariants(), 'h-9 w-full'), children: [_jsx("span", { className: "truncate", children: displayName }), disabled ? null : _jsx(ChevronDown, { className: cn(TRIGGER_CARET_CLASS, 'size-4') })] })) : (_jsxs(Button, { type: "button", variant: triggerVariant, size: "sm",
308
+ // `min-w-0 shrink`: in a narrow toolbar (a channel's thread panel) the
309
+ // model name truncates; the controls beside it keep their width.
310
+ className: cn('min-w-0 shrink rounded-lg hit-area-y-3', triggerVariant === 'ghost' && 'text-muted-foreground'), children: [_jsx("span", { className: cn('max-w-30 truncate', triggerLabelClassName), children: displayName }), _jsx(ChevronDown, { className: cn('duration-moderate size-3 transition-transform ease-out', open && 'rotate-180') })] })) }), _jsx(CommandPopoverContent, { side: "top", align: "start", sideOffset: 8, className: "w-[min(300px,calc(100vw-1.5rem))]", children: _jsxs(_Fragment, { children: [_jsx(CommandInput, { compact: true, placeholder: tModel('search'), value: search, onValueChange: setSearch, rightElement: canManageModels && canConnectProvider ? (_jsxs("div", { className: "-mr-0.5 flex shrink-0 items-center gap-0.5", children: [_jsx(Hint, { label: tModel('connectProvider'), side: "top", className: "z-50", children: _jsx("button", { type: "button", "aria-label": tModel('addProvider'), onClick: () => handleOpenProviderModal('providers'), className: "text-muted-foreground hover:text-foreground hover:bg-muted flex size-8 cursor-pointer items-center justify-center rounded-md transition-colors", children: _jsx(Plus, { className: "size-4" }) }) }), _jsx(Hint, { label: tModel('manageModels'), side: "top", className: "z-50", children: _jsx("button", { type: "button", "aria-label": tModel('manageModels'), onClick: () => handleOpenProviderModal('models'), className: "text-muted-foreground hover:text-foreground hover:bg-muted flex size-8 cursor-pointer items-center justify-center rounded-md transition-colors", children: _jsx(SlidersHorizontal, { className: "size-4" }) }) })] })) : undefined }), grouped.length > 1 && _jsx(CommandSeparator, { className: "bg-border/60" }), _jsx(CommandList, { className: "max-h-[380px]", children: modelsLoading || entitlementsPending ? (_jsx("div", { className: "flex min-h-32 items-center justify-center", role: "status", "aria-label": tModel('loading'), children: _jsx(Loading, { className: "text-muted-foreground size-4 shrink-0" }) })) : grouped.length > 0 ? (_jsxs(_Fragment, { children: [pinnedDefault && (_jsxs(_Fragment, { children: [_jsx(CommandGroup, { heading: _jsx(GroupHeading, { children: tModel('yourDefault') }), forceMount: true, children: _jsx(ModelRow, { model: pinnedDefault.model, groupProviderID: pinnedDefault.providerID, groupProviderName: pinnedDefault.providerName, isSelected: availableSelectedModel?.providerID === pinnedDefault.model.providerID &&
308
311
  availableSelectedModel?.modelID === pinnedDefault.model.modelID, isAccountDefault: true, defaultControls: rowDefaultControls, onSelect: handleSelect, connectLabel: tPooled('connect'), scope: "pinned" }) }), _jsx(CommandSeparator, {})] })), sections.map((section, sectionIndex) => {
309
312
  const selectedInSection = section.models.find((m) => availableSelectedModel?.providerID === m.providerID &&
310
313
  availableSelectedModel?.modelID === m.modelID);
@@ -12,11 +12,9 @@ export declare function projectProviderModalTab(tab: ProviderModalTab): 'provide
12
12
  * route segment is the fallback.
13
13
  *
14
14
  * The fallback is what every original caller relies on — they all render under
15
- * `/projects/[id]`. The explicit id exists because the onboarding wizard's plan
16
- * step now also runs on `/new` (`app/(app)/new`), which has NO `[id]` segment:
17
- * there the route yields `null`, `modal` is therefore `null`, and
18
- * `openConnectProvider` renders nothing while the step's only control never
19
- * advances the wizard.
15
+ * `/projects/[id]`. The explicit id serves callers outside that route, such as
16
+ * Customize's provider list: there the route may yield `null`, `modal` is
17
+ * then `null`, and `openConnectProvider` renders nothing.
20
18
  *
21
19
  * `!== undefined`, never `??`: a caller that deliberately passes `null` means
22
20
  * "act on no project", and must not silently inherit whatever route it happens
@@ -47,6 +45,8 @@ export declare function useModelConnectionGate(models?: FlatModel[], options?: {
47
45
  projectId?: string | null;
48
46
  }): {
49
47
  canConnectProvider: boolean;
48
+ /** The viewer holds `project.model.write`: the provider modal can change the project's models. */
49
+ canWriteProviders: boolean;
50
50
  openConnectProvider: (tab?: ProviderModalTab) => void;
51
51
  openUpgrade: () => void;
52
52
  modal: import("react").JSX.Element | null;
@@ -27,11 +27,9 @@ export function projectProviderModalTab(tab) {
27
27
  * route segment is the fallback.
28
28
  *
29
29
  * The fallback is what every original caller relies on — they all render under
30
- * `/projects/[id]`. The explicit id exists because the onboarding wizard's plan
31
- * step now also runs on `/new` (`app/(app)/new`), which has NO `[id]` segment:
32
- * there the route yields `null`, `modal` is therefore `null`, and
33
- * `openConnectProvider` renders nothing while the step's only control never
34
- * advances the wizard.
30
+ * `/projects/[id]`. The explicit id serves callers outside that route, such as
31
+ * Customize's provider list: there the route may yield `null`, `modal` is
32
+ * then `null`, and `openConnectProvider` renders nothing.
35
33
  *
36
34
  * `!== undefined`, never `??`: a caller that deliberately passes `null` means
37
35
  * "act on no project", and must not silently inherit whatever route it happens
@@ -154,6 +152,8 @@ export function useModelConnectionGate(models = [], options) {
154
152
  const showUpgradeOption = !!platformConfig().billingEnabled;
155
153
  return {
156
154
  canConnectProvider,
155
+ /** The viewer holds `project.model.write`: the provider modal can change the project's models. */
156
+ canWriteProviders,
157
157
  openConnectProvider,
158
158
  openUpgrade,
159
159
  modal,
@@ -0,0 +1,10 @@
1
+ import { type LoadEntireHistoryOptions } from '../print/load-entire-history.js';
2
+ /** Resolve again after paging: older pages can change the first loaded turn's anchor. */
3
+ export declare function jumpToOutcome({ needsHistory, history, resolve, scroll, unavailable, loadError }: {
4
+ needsHistory: boolean;
5
+ history: LoadEntireHistoryOptions;
6
+ resolve: () => string | undefined;
7
+ scroll: (key: string) => Promise<boolean>;
8
+ unavailable: () => void;
9
+ loadError: () => void;
10
+ }): Promise<void>;
@@ -0,0 +1,11 @@
1
+ import { loadEntireHistory } from '../print/load-entire-history.js';
2
+ /** Resolve again after paging: older pages can change the first loaded turn's anchor. */
3
+ export async function jumpToOutcome({ needsHistory, history, resolve, scroll, unavailable, loadError }) {
4
+ if (needsHistory && !(await loadEntireHistory(history)).exhausted) {
5
+ loadError();
6
+ return;
7
+ }
8
+ const key = resolve();
9
+ if (!key || !await scroll(key))
10
+ unavailable();
11
+ }
@@ -0,0 +1,14 @@
1
+ import { type Dispatch, type ReactNode, type SetStateAction } from 'react';
2
+ import type { ChangeRequest } from '@kortix/sdk';
3
+ export interface SessionChangeRequests {
4
+ requests: ChangeRequest[];
5
+ onOpen: (crId: string) => void;
6
+ onJump: (crId: string) => Promise<void>;
7
+ jumping: boolean;
8
+ }
9
+ /** Chat and the mobile panel are siblings. Share the existing read, never a second query. */
10
+ export declare function SessionOutcomesBridge({ children }: {
11
+ children: ReactNode;
12
+ }): import("react").JSX.Element;
13
+ export declare const useSessionChangeRequestsPanel: () => SessionChangeRequests | null;
14
+ export declare const usePublishSessionChangeRequests: () => Dispatch<SetStateAction<SessionChangeRequests | null>> | null;
@@ -0,0 +1,12 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createContext, useContext, useState } from 'react';
4
+ const ReadContext = createContext(null);
5
+ const WriteContext = createContext(null);
6
+ /** Chat and the mobile panel are siblings. Share the existing read, never a second query. */
7
+ export function SessionOutcomesBridge({ children }) {
8
+ const [value, setValue] = useState(null);
9
+ return (_jsx(WriteContext.Provider, { value: setValue, children: _jsx(ReadContext.Provider, { value: value, children: children }) }));
10
+ }
11
+ export const useSessionChangeRequestsPanel = () => useContext(ReadContext);
12
+ export const usePublishSessionChangeRequests = () => useContext(WriteContext);
@@ -1,7 +1,7 @@
1
1
  import { type ReactNode } from 'react';
2
2
  import { type TurnSpan } from './anchor-outcomes.js';
3
3
  import type { Outcome } from '../../internal/outcomes/outcome-types.js';
4
- export declare function SessionOutcomesProvider({ projectSessionId, turnSpans, busy, onOpen, children, }: {
4
+ export declare function SessionOutcomesProvider({ projectSessionId, turnSpans, busy, onOpen, children, onJump, jumping, }: {
5
5
  /** The git session id a change request records as `origin_session_id`. */
6
6
  projectSessionId: string | undefined;
7
7
  turnSpans: TurnSpan[];
@@ -9,6 +9,8 @@ export declare function SessionOutcomesProvider({ projectSessionId, turnSpans, b
9
9
  busy: boolean;
10
10
  onOpen: (outcome: Outcome) => void;
11
11
  children: ReactNode;
12
+ onJump: (resolveTurn: () => string | undefined, createdAt: number) => Promise<void>;
13
+ jumping: boolean;
12
14
  }): import("react").JSX.Element;
13
15
  /** A turn's outcomes, oldest first. `EMPTY` is a module constant so a turn with
14
16
  * no outcomes gets the SAME array every render and never re-renders for it. */
@@ -45,6 +45,9 @@ import { useProjectContext } from '../../files/project/context.js';
45
45
  // NOT `@kortix/sdk/react`'s change-request hook. See the note above — this is
46
46
  // a cache-coherence requirement, not a style preference.
47
47
  import { invalidateChangeRequestReads, useSessionChangeRequests, } from '../../files/project/hooks/use-change-requests.js';
48
+ import { usePublishSessionChangeRequests } from './session-outcomes-bridge.js';
49
+ import { useProjectCan } from '../../internal/lib/use-project-can.js';
50
+ import { PROJECT_ACTIONS } from '../../internal/lib/project-actions.js';
48
51
  import { anchorOutcomes } from './anchor-outcomes.js';
49
52
  import { changeRequestOutcomes } from './change-request-outcomes.js';
50
53
  const EMPTY = [];
@@ -52,7 +55,7 @@ const OutcomesContext = createContext(null);
52
55
  /** A change request the agent opens as its turn closes can land after the
53
56
  * turn-end read: read once more after this delay. */
54
57
  const CHANGE_REQUEST_SETTLE_MS = 2_500;
55
- export function SessionOutcomesProvider({ projectSessionId, turnSpans, busy, onOpen, children, }) {
58
+ export function SessionOutcomesProvider({ projectSessionId, turnSpans, busy, onOpen, children, onJump, jumping, }) {
56
59
  const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
57
60
  // No `projectId` argument: this hook reads it from `ProjectFilesProvider`,
58
61
  // which is what keeps it on the same cache entry the dialog invalidates.
@@ -60,15 +63,42 @@ export function SessionOutcomesProvider({ projectSessionId, turnSpans, busy, onO
60
63
  // the turn that produced it — it just reads "Applied" or "Closed".
61
64
  // Only THIS session's change requests, filtered by the server; the key sits
62
65
  // under the project-files list scope the dialog's mutations invalidate.
63
- const { data } = useSessionChangeRequests(projectSessionId, { refetchInterval: 60_000 });
66
+ const projectId = useProjectContext()?.projectId;
67
+ const { allowed } = useProjectCan(projectId, PROJECT_ACTIONS.PROJECT_GITOPS_READ);
68
+ const { data } = useSessionChangeRequests(projectSessionId, { refetchInterval: busy ? 5_000 : 60_000, enabled: allowed });
69
+ const requests = useMemo(() => allowed ? (data?.change_requests ?? []) : [], [allowed, data?.change_requests]);
64
70
  useRefreshChangeRequestsOnTurnEnd(busy);
65
71
  const all = useMemo(
66
72
  // Change requests are the only outcome a turn produces. The derived
67
73
  // pipeline (files, schedules, background tasks, connector links) was built
68
74
  // and removed — see `OutcomeKind` for why each one could not be tied to the
69
75
  // turn that showed it.
70
- () => changeRequestOutcomes(data?.change_requests ?? [], projectSessionId, tI18nComplete), [data?.change_requests, projectSessionId, tI18nComplete]);
76
+ () => changeRequestOutcomes(requests, projectSessionId, tI18nComplete), [requests, projectSessionId, tI18nComplete]);
71
77
  const byTurn = useMemo(() => anchorOutcomes(all, turnSpans), [all, turnSpans]);
78
+ const anchorsRef = useRef(byTurn);
79
+ useEffect(() => { anchorsRef.current = byTurn; }, [byTurn]);
80
+ const publish = usePublishSessionChangeRequests();
81
+ const panelValue = useMemo(() => ({
82
+ requests,
83
+ onOpen: (crId) => {
84
+ const outcome = all.find((item) => item.id === `cr:${crId}`);
85
+ // Rows open this request, not a superseding request's detail.
86
+ if (outcome)
87
+ onOpen({ ...outcome, action: { ...outcome.action, target: crId } });
88
+ },
89
+ onJump: (crId) => onJump(() => {
90
+ for (const [key, outcomes] of anchorsRef.current) {
91
+ if (outcomes.some((item) => item.id === `cr:${crId}`))
92
+ return key;
93
+ }
94
+ return undefined;
95
+ }, Date.parse(requests.find((cr) => cr.cr_id === crId)?.created_at ?? '')),
96
+ jumping,
97
+ }), [requests, all, onOpen, onJump, jumping]);
98
+ useEffect(() => {
99
+ publish?.(panelValue);
100
+ return () => publish?.(null);
101
+ }, [publish, panelValue]);
72
102
  const value = useMemo(() => ({ byTurn, onOpen }), [byTurn, onOpen]);
73
103
  return _jsx(OutcomesContext.Provider, { value: value, children: children });
74
104
  }
@@ -1,3 +1,4 @@
1
+ import { type ReactNode } from 'react';
1
2
  import { type ShareContext } from '../../../files/viewer/viewer-actions.js';
2
3
  export declare function AppPreview({ url, name, projectId, shareContext, onClose, onSendToAgent, }: {
3
4
  /** The internal sandbox URL the agent handed over, e.g. http://localhost:3000. */
@@ -17,3 +18,12 @@ export declare function AppPreview({ url, name, projectId, shareContext, onClose
17
18
  * shows only Retry, exactly as before. */
18
19
  onSendToAgent?: () => void;
19
20
  }): import("react").JSX.Element;
21
+ /**
22
+ * The Browser card while the session's computer boots: the real toolbar, every
23
+ * control that needs the computer disabled, over `children` (the boot status).
24
+ * Mounts nothing that reaches the sandbox: no proxy, no app list, no frame.
25
+ */
26
+ export declare function AppPreviewBooting({ onClose, children, }: {
27
+ onClose: () => void;
28
+ children: ReactNode;
29
+ }): import("react").JSX.Element;
@@ -36,7 +36,7 @@ import { useBrowserRecentsStore } from '../../../internal/stores/browser-recents
36
36
  import { probePreviewPort } from '@kortix/sdk';
37
37
  import { useRuntimeConnectionStore } from '@kortix/sdk/react';
38
38
  import { ArrowSquareOutIcon, GlobeIcon as Globe, SparkleIcon as SparklesSolid, WarningIcon, } from '@phosphor-icons/react';
39
- import { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';
39
+ import { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore, } from 'react';
40
40
  import { PreviewLoadingOverlay, SandboxAddressBar, } from '../../../browser/sandbox-browser-chrome.js';
41
41
  import { BrowserLanding } from '../../../browser/browser-landing.js';
42
42
  import { CloseButton, DetailSidebarToggle } from './detail-view.js';
@@ -97,7 +97,6 @@ export function AppPreview({ url, name, projectId, shareContext, onClose, onSend
97
97
  // Still loading past PREVIEW_SLOW_MS: the overlay says so and offers Reload.
98
98
  const [slow, setSlow] = useState(false);
99
99
  const addressRef = useRef(null);
100
- const isMobile = useIsMobile();
101
100
  // Copy link mints a PUBLIC share and copies `/share/session/{token}`.
102
101
  // It used to copy `previewUrl` — the authenticated `/v1/p/{sandbox}/{port}/…`
103
102
  // proxy URL — which only ever worked in the tab that had the
@@ -235,16 +234,11 @@ export function AppPreview({ url, name, projectId, shareContext, onClose, onSend
235
234
  setIndex((i) => i + 1);
236
235
  reload();
237
236
  }, [canGoForward, reload]);
238
- return (_jsxs("div", { className: "bg-background flex h-full min-h-0 min-w-0 flex-col", children: [_jsxs("div", { className: "border-border flex shrink-0 items-center gap-0.5 border-b px-2 py-1", children: [_jsx(DetailSidebarToggle, {}), _jsx(SandboxAddressBar, { displayValue: current, hasPreview: hasPreview, isLoading: isLoading, canGoBack: canGoBack, canGoForward: canGoForward, onBack: goBack, onForward: goForward, onReload: reload, onHome: () => navigateTo(''), onNavigate: navigateTo, suggestions: suggestions, placeholder: tI18nComplete.raw('text878abd024f27'), inputRef: addressRef, trailing:
239
- // An app has no file to save and no text to put on a clipboard, so
240
- // `Copy link` is the one copy action — the thing you can hand
241
- // someone for a running port.
242
- _jsx(ViewerActions, { copy: appCopy, shareContext: shareContext, shareInput: shareInput }) }), _jsxs(ButtonGroup, { className: "shrink-0", children: [_jsx(Hint, { label: tI18nComplete.raw('text306ef19c8ac3'), side: "bottom", children: _jsx(Button, { variant: "secondary", size: "icon", disabled: !hasPreview, "aria-label": tI18nComplete.raw('text306ef19c8ac3'), onClick: () => {
243
- if (!previewUrl)
244
- return;
245
- track('app_opened_new_tab');
246
- window.open(previewUrl, '_blank', 'noopener,noreferrer');
247
- }, className: "size-7 shrink-0 active:scale-[0.96]", children: _jsx(ArrowSquareOutIcon, { className: "size-3.5" }) }) }), _jsx(PanelWidthButton, { isMobile: isMobile }), _jsx(CloseButton, { onClose: onClose })] })] }), _jsxs("div", { className: "relative min-h-0 flex-1 overflow-hidden", children: [isLoading && hasPreview && !noApp && (_jsx(PreviewLoadingOverlay, { label: tI18nComplete.raw('textc4cf2b2ccb5d'), detail: slow ? previewSlowReason({ port }) : undefined, action: slow ? (_jsx(Button, { variant: "outline", size: "sm", className: "gap-1.5", onClick: reload, children: tI18nComplete.raw('textbdc090ec61e3') })) : undefined })), (hasError || hostPreview.failed) && !noApp && (_jsx(ErrorState, { icon: WarningIcon, size: "sm", className: "bg-background absolute inset-0 z-10", title: tI18nComplete('textba601cdb484b', { value0: title }),
237
+ return (_jsxs("div", { className: "bg-background flex h-full min-h-0 min-w-0 flex-col", children: [_jsx(AppPreviewToolbar, { previewUrl: previewUrl, onClose: onClose, displayValue: current, isLoading: isLoading, canGoBack: canGoBack, canGoForward: canGoForward, onBack: goBack, onForward: goForward, onReload: reload, onHome: () => navigateTo(''), onNavigate: navigateTo, suggestions: suggestions, inputRef: addressRef, trailing:
238
+ // An app has no file to save and no text to put on a clipboard, so
239
+ // `Copy link` is the one copy action — the thing you can hand
240
+ // someone for a running port.
241
+ _jsx(ViewerActions, { copy: appCopy, shareContext: shareContext, shareInput: shareInput }) }), _jsxs("div", { className: "relative min-h-0 flex-1 overflow-hidden", children: [isLoading && hasPreview && !noApp && (_jsx(PreviewLoadingOverlay, { label: tI18nComplete.raw('textc4cf2b2ccb5d'), detail: slow ? previewSlowReason({ port }) : undefined, action: slow ? (_jsx(Button, { variant: "outline", size: "sm", className: "gap-1.5", onClick: reload, children: tI18nComplete.raw('textbdc090ec61e3') })) : undefined })), (hasError || hostPreview.failed) && !noApp && (_jsx(ErrorState, { icon: WarningIcon, size: "sm", className: "bg-background absolute inset-0 z-10", title: tI18nComplete('textba601cdb484b', { value0: title }),
248
242
  /* The single most common cause, said plainly: the agent started the
249
243
  server a moment ago and it isn't listening yet. Only a SETTLED
250
244
  `dead` verdict earns the stopped-workspace wording — see
@@ -274,6 +268,31 @@ export function AppPreview({ url, name, projectId, shareContext, onClose, onSend
274
268
  // frame reads as "your app is broken".
275
269
  _jsx("div", { className: "flex h-full items-center justify-center", children: _jsx(Loading, { className: "size-4" }) }))] })] }));
276
270
  }
271
+ /**
272
+ * The Browser card's toolbar: sidebar toggle, address bar, open in a new tab,
273
+ * width, close. Shared by the live preview and the booting card, so the two
274
+ * cannot drift.
275
+ */
276
+ function AppPreviewToolbar({ previewUrl, onClose, ...address }) {
277
+ const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
278
+ const isMobile = useIsMobile();
279
+ return (_jsxs("div", { className: "border-border flex shrink-0 items-center gap-0.5 border-b px-2 py-1", children: [_jsx(DetailSidebarToggle, {}), _jsx(SandboxAddressBar, { ...address, hasPreview: !!previewUrl, placeholder: tI18nComplete.raw('text878abd024f27') }), _jsxs(ButtonGroup, { className: "shrink-0", children: [_jsx(Hint, { label: tI18nComplete.raw('text306ef19c8ac3'), side: "bottom", children: _jsx(Button, { variant: "secondary", size: "icon", disabled: !previewUrl, "aria-label": tI18nComplete.raw('text306ef19c8ac3'), onClick: () => {
280
+ if (!previewUrl)
281
+ return;
282
+ track('app_opened_new_tab');
283
+ window.open(previewUrl, '_blank', 'noopener,noreferrer');
284
+ }, className: "size-7 shrink-0 active:scale-[0.96]", children: _jsx(ArrowSquareOutIcon, { className: "size-3.5" }) }) }), _jsx(PanelWidthButton, { isMobile: isMobile }), _jsx(CloseButton, { onClose: onClose })] })] }));
285
+ }
286
+ const noop = () => { };
287
+ /**
288
+ * The Browser card while the session's computer boots: the real toolbar, every
289
+ * control that needs the computer disabled, over `children` (the boot status).
290
+ * Mounts nothing that reaches the sandbox: no proxy, no app list, no frame.
291
+ */
292
+ export function AppPreviewBooting({ onClose, children, }) {
293
+ const addressRef = useRef(null);
294
+ return (_jsxs("div", { className: "bg-background flex h-full min-h-0 min-w-0 flex-col", children: [_jsx(AppPreviewToolbar, { onClose: onClose, displayValue: "", isLoading: false, canGoBack: false, canGoForward: false, onBack: noop, onForward: noop, onReload: noop, onHome: noop, onNavigate: noop, inputRef: addressRef, disabled: true }), _jsx("div", { className: "relative min-h-0 flex-1 overflow-hidden", children: children })] }));
295
+ }
277
296
  function SearchHint() {
278
297
  const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
279
298
  return (_jsx("div", { className: "flex flex-1 items-center justify-center", children: _jsxs("div", { className: "text-muted-foreground flex flex-col items-center gap-4 px-4 text-center", children: [_jsx(Globe, { className: "size-12 opacity-20" }), _jsx("p", { className: "text-sm", children: tI18nComplete.raw('text2f883b75cd2d') })] }) }));
@@ -0,0 +1,7 @@
1
+ import type { ChangeRequest } from '@kortix/sdk';
2
+ export declare function ChangeRequestsCard({ requests, onOpen, onJump, jumping }: {
3
+ requests: ChangeRequest[];
4
+ onOpen: (crId: string) => void;
5
+ onJump: (crId: string) => Promise<void>;
6
+ jumping?: boolean;
7
+ }): import("react").JSX.Element | null;
@@ -0,0 +1,17 @@
1
+ 'use client';
2
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
3
+ import { ArrowBendUpLeftIcon } from '@phosphor-icons/react';
4
+ import { useLocale, useTranslations } from '../../../i18n/index.js';
5
+ import { relativeTime } from '../../../internal/lib/relative-time.js';
6
+ import { ChangeRequestStatusBadge } from '../../../files/project/components/change-request-status-badge.js';
7
+ import { Badge } from '../../../primitives/badge.js';
8
+ import { Button } from '../../../primitives/button.js';
9
+ import Hint from '../../../primitives/hint.js';
10
+ import { PanelCard } from './panel-card.js';
11
+ export function ChangeRequestsCard({ requests, onOpen, onJump, jumping = false }) {
12
+ const t = useTranslations('sessionChangeRequests');
13
+ const locale = useLocale();
14
+ if (requests.length === 0)
15
+ return null;
16
+ return (_jsx(PanelCard, { title: t('title'), count: requests.length, isEmpty: false, defaultExpanded: true, fill: true, contentClassName: "min-h-0 overflow-y-auto px-2 py-2", children: _jsx("ul", { children: [...requests].sort((a, b) => Date.parse(b.created_at) - Date.parse(a.created_at)).map((cr) => (_jsxs("li", { className: "flex items-center gap-1", children: [_jsxs("button", { type: "button", "data-cr-id": cr.cr_id, onClick: () => onOpen(cr.cr_id), className: "hover:bg-accent flex min-w-0 flex-1 flex-col gap-1 rounded-sm px-2 py-2 text-left", children: [_jsxs("span", { className: "flex w-full min-w-0 items-baseline gap-2", children: [_jsxs("span", { className: "text-muted-foreground shrink-0 text-xs tabular-nums", children: ["#", cr.number] }), _jsx("span", { className: "text-foreground truncate text-sm", children: cr.title })] }), _jsxs("span", { className: "flex flex-wrap items-center gap-2", children: [cr.status === 'open' ? _jsx(Badge, { variant: "secondary", size: "sm", children: t('open') }) : _jsx(ChangeRequestStatusBadge, { cr: cr }), _jsx("time", { dateTime: cr.created_at, className: "text-muted-foreground text-xs", children: relativeTime(cr.created_at, locale) })] })] }), _jsx(Hint, { label: t('jump', { number: cr.number }), children: _jsx(Button, { variant: "ghost", size: "icon", disabled: jumping, "aria-label": t('jump', { number: cr.number }), onClick: () => onJump(cr.cr_id), children: _jsx(ArrowBendUpLeftIcon, { className: "size-3.5 shrink-0" }) }) })] }, cr.cr_id))) }) }));
17
+ }
@@ -2,6 +2,7 @@
2
2
  * Pure logic for `EasyPanel`, split out from the client component purely so
3
3
  * it is unit-testable without a DOM.
4
4
  */
5
+ import { parseArtifactUrl } from '../../../artifacts/frame-policy.js';
5
6
  import { isKortixAppUrl } from '../../../apps/kortix-app-url.js';
6
7
  import { parseLocalhostUrl } from '@kortix/sdk';
7
8
  /**
@@ -43,6 +44,10 @@ export function quickBrowserOutput(apps,
43
44
  * wrong page.
44
45
  */
45
46
  target) {
47
+ // An artifact's app link opens as the artifact (the browser cannot frame the Kortix app).
48
+ if (target?.url && parseArtifactUrl(target.url)) {
49
+ return { callID: 'quick-browser', name: target.title || 'Artifact', kind: 'artifact', url: target.url };
50
+ }
46
51
  return {
47
52
  callID: 'quick-browser',
48
53
  name: target?.title || 'Browser',
@@ -98,7 +103,7 @@ export function sandboxRecents(recents) {
98
103
  * - web pages (`.html/.htm` — same viewport assumption as apps).
99
104
  */
100
105
  export function isWideDeliverable(output) {
101
- if (output.kind === 'presentation' || output.kind === 'app')
106
+ if (output.kind === 'presentation' || output.kind === 'app' || output.kind === 'artifact')
102
107
  return true;
103
108
  return /\.(pptx?|key|xlsx?|csv|tsv|html?)$/i.test(output.name);
104
109
  }
@@ -168,6 +173,7 @@ export function deriveIsRunning(stepsRunning, sessionBusy) {
168
173
  * "Apps"). */
169
174
  const KIND_GROUP_LABEL = {
170
175
  app: 'Apps',
176
+ artifact: 'Artifacts',
171
177
  presentation: 'Presentations',
172
178
  image: 'Images',
173
179
  video: 'Videos',
@@ -29,6 +29,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
29
29
  import { usePlanInChat } from '../../thread/plan-surface.js';
30
30
  import { useSessionComposerPrefillStore } from '../../composer/stores/session-composer-prefill-store.js';
31
31
  import { useOptionalSessionPanel } from '../session-panel-provider.js';
32
+ import { useSessionChangeRequestsPanel } from '../../outcomes/session-outcomes-bridge.js';
33
+ import { ChangeRequestsCard } from './change-requests-card.js';
32
34
  import { AppsCard } from './apps-card.js';
33
35
  import { ContextCard } from './context-card.js';
34
36
  import { pathOutput } from './easy-panel-logic.js';
@@ -36,6 +38,7 @@ import { OutputsCard } from './outputs-card.js';
36
38
  import { PlanPanelCard } from './plan-card.js';
37
39
  export function EasyPanel() {
38
40
  const panel = useOptionalSessionPanel();
41
+ const changeRequests = useSessionChangeRequestsPanel();
39
42
  // Exactly one plan surface is mounted, ever. This card stands down only on
40
43
  // mobile, where this same component is the detail drawer's home view and the
41
44
  // drawer is shut by default, so the transcript keeps the plan. On desktop it
@@ -58,9 +61,9 @@ export function EasyPanel() {
58
61
  // through everything above them.
59
62
  //
60
63
  // Now the column owns the height (`h-full`) and hands the leftover to
61
- // exactly one card. Outputs is the one that yields (`fill`); Context and
64
+ // exactly one card: Change requests when present, otherwise Outputs. Context and
62
65
  // Preview keep `shrink-0` and stay on screen at their full height, always.
63
66
  // `min-h-0` is what lets this shrink at all — a flex container defaults to
64
67
  // its content's minimum height and would otherwise refuse.
65
- _jsxs("div", { className: "flex h-full min-h-0 flex-col gap-2", children: [_jsx(OutputsCard, { outputs: files, defaultExpanded: outputsDefaultOpen, onOpenOutput: (o) => handleOpenOutput(o, files) }), _jsx(ContextCard, { files: context.files, web: context.web, tools: context.tools, sessionId: sessionId, onOpenDetail: openDetail, onOpenFile: (path, allPaths) => handleOpenOutput(pathOutput(path), allPaths.map(pathOutput)), onAddContext: () => useSessionComposerPrefillStore.getState().requestAttach(sessionId) }), apps.length > 0 && _jsx(AppsCard, { apps: apps, onOpenApp: (a) => handleOpenOutput(a, apps) }), !planInChat && _jsx(PlanPanelCard, { sessionId: sessionId })] }));
68
+ _jsxs("div", { className: "flex h-full min-h-0 flex-col gap-2", children: [_jsx(OutputsCard, { fill: !changeRequests?.requests.length, outputs: files, defaultExpanded: outputsDefaultOpen, onOpenOutput: (o) => handleOpenOutput(o, files) }), _jsx(ContextCard, { files: context.files, web: context.web, tools: context.tools, sessionId: sessionId, onOpenDetail: openDetail, onOpenFile: (path, allPaths) => handleOpenOutput(pathOutput(path), allPaths.map(pathOutput)), onAddContext: () => useSessionComposerPrefillStore.getState().requestAttach(sessionId) }), apps.length > 0 && _jsx(AppsCard, { apps: apps, onOpenApp: (a) => handleOpenOutput(a, apps) }), !planInChat && _jsx(PlanPanelCard, { sessionId: sessionId }), changeRequests && _jsx(ChangeRequestsCard, { ...changeRequests })] }));
66
69
  }
@@ -215,7 +215,7 @@ export function FilePreview({ path, name, fileName = name, shareContext, onClose
215
215
  setPanelAspect(null);
216
216
  }, [setPanelAspect]);
217
217
  if (rich) {
218
- return (_jsx(PreviewShell, { name: name, shareContext: shareContext, fileName: fileName, path: path, onClose: onClose, onPresent: onPresent, refresh: refresh, children: _jsx(FileSourceProvider, { value: workspaceFileSource, children: _jsx(PreviewFitProvider, { onMeasure: ({ width, height }) => setPanelAspect(width / height), onUnmeasurable: () => setPanelAspect(null), children: _jsx(FileContentRenderer, { filePath: path, reloadKey: reloadKey, showHeader: false, className: "h-full", fitOnOpen: isPdf, onStatusChange: handleStatusChange }) }) }) }));
218
+ return (_jsx(PreviewShell, { name: name, shareContext: shareContext, fileName: fileName, path: path, onClose: onClose, onPresent: onPresent, refresh: refresh, children: _jsx(FileSourceProvider, { value: workspaceFileSource, children: _jsx(PreviewFitProvider, { onMeasure: ({ width, height }) => setPanelAspect(width / height), onUnmeasurable: () => setPanelAspect(null), children: _jsx(FileContentRenderer, { filePath: path, reloadKey: reloadKey, showCaption: true, showHeader: false, className: "h-full", fitOnOpen: isPdf, onStatusChange: handleStatusChange }) }) }) }));
219
219
  }
220
220
  if (isLoading) {
221
221
  return (_jsx(PreviewShell, { name: name, shareContext: shareContext, fileName: fileName, path: path, onClose: onClose, onPresent: onPresent, refresh: refresh, children: _jsx(Centered, { children: _jsx(Loading, {}) }) }));
@@ -14,8 +14,9 @@ export declare function OutputRows({ outputs, onOpenOutput, initialShowAll, }: {
14
14
  */
15
15
  initialShowAll?: boolean;
16
16
  }): import("react").JSX.Element;
17
- export declare function OutputsCard({ outputs, defaultExpanded, onOpenOutput, }: {
17
+ export declare function OutputsCard({ outputs, defaultExpanded, onOpenOutput, fill, }: {
18
18
  outputs: OutputItem[];
19
+ fill?: boolean;
19
20
  /** Auto-expands when a run finishes with something to show — the payoff moment. */
20
21
  defaultExpanded: boolean;
21
22
  onOpenOutput: (output: OutputItem) => void;
@@ -34,6 +34,7 @@ const KIND_ICON = {
34
34
  video: VideoIcon,
35
35
  presentation: PresentationIcon,
36
36
  app: AppWindow,
37
+ artifact: FileText,
37
38
  };
38
39
  /** `callID:path` → object URL, shared across rows and re-renders. Keyed by
39
40
  * call, not bare path: paths repeat across sessions (`output.png`), and callID
@@ -193,9 +194,9 @@ function DownloadAllAction({ outputs }) {
193
194
  };
194
195
  return (_jsx(Hint, { label: tI18nComplete.raw('textf7917eced9c2'), side: "bottom", children: _jsx(Button, { variant: "ghost", size: "icon", onClick: () => void handleDownload(), disabled: busy, "aria-label": tI18nComplete.raw('textf7917eced9c2'), "aria-busy": busy, className: "size-7 active:scale-[0.96] disabled:opacity-100", children: busy ? (_jsx(Loading, { className: "text-muted-foreground size-3.5 motion-reduce:animate-none" })) : (_jsx(Download, { className: "size-3.5" })) }) }));
195
196
  }
196
- export function OutputsCard({ outputs, defaultExpanded, onOpenOutput, }) {
197
+ export function OutputsCard({ outputs, defaultExpanded, onOpenOutput, fill = true, }) {
197
198
  const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
198
- return (_jsx(PanelCard, { title: tI18nComplete.raw('texte7ce99764a2d'), count: outputs.length, isEmpty: outputs.length === 0, defaultExpanded: defaultExpanded, emptyArt: _jsx(OutputsArt, {}), emptyText: tI18nComplete.raw('textd5f2ad00f99b'), contentClassName: "flex min-h-0 flex-col px-2 py-2", fill: true, headerAction: _jsx(DownloadAllAction, { outputs: outputs }), children: _jsx(OutputRows, { outputs: outputs, onOpenOutput: onOpenOutput }) }));
199
+ return (_jsx(PanelCard, { title: tI18nComplete.raw('texte7ce99764a2d'), count: outputs.length, isEmpty: outputs.length === 0, defaultExpanded: defaultExpanded, emptyArt: _jsx(OutputsArt, {}), emptyText: tI18nComplete.raw('textd5f2ad00f99b'), contentClassName: cn('flex min-h-0 flex-col px-2 py-2', !fill && 'max-h-40 overflow-y-auto'), fill: fill, headerAction: _jsx(DownloadAllAction, { outputs: outputs }), children: _jsx(OutputRows, { outputs: outputs, onOpenOutput: onOpenOutput }) }));
199
200
  }
200
201
  /**
201
202
  * Soft placeholder art — a stacked-document glyph, matching the reference.
@@ -24,6 +24,8 @@ import { SessionAuditPanel } from './session-audit-panel.js';
24
24
  import { SessionRemindersPanel } from './session-reminders-panel.js';
25
25
  import { SessionFilesExplorer } from './session-files-explorer.js';
26
26
  import { SessionTerminalPanel } from '../../terminal/session-terminal-panel.js';
27
+ import { SessionBootStatus } from '../status/session-starting-loader.js';
28
+ import { useOptionalSessionPanel } from './session-panel-provider.js';
27
29
  import { useLocalizedUiCatalog } from '../../i18n/ui-catalog/use-localized-ui-catalog.js';
28
30
  import { useKortixComputerStore } from '../../internal/stores/kortix-computer-store.js';
29
31
  import { sessionPreviewTabId } from '../../internal/stores/session-browser-store.js';
@@ -40,5 +42,9 @@ export function MobileToolDrawer({ sessionId, projectId, projectSessionId, }) {
40
42
  const closeMobileTool = useKortixComputerStore((s) => s.closeMobileTool);
41
43
  const toolMeta = useLocalizedUiCatalog(TOOL_META);
42
44
  const meta = view ? toolMeta[view] : null;
43
- return (_jsx(Drawer, { open: view !== null, onOpenChange: (next) => !next && closeMobileTool(), children: _jsxs(DrawerContent, { className: "flex h-[95dvh] max-h-[95dvh] min-h-[95dvh] flex-col overflow-hidden p-0", children: [_jsx(DrawerHeader, { className: "shrink-0 px-4 py-3 text-left", children: _jsxs(DrawerTitle, { className: "flex items-center justify-between gap-2 text-base", children: [_jsxs("span", { className: "flex items-center gap-2.5", children: [meta && _jsx(meta.Icon, { className: "text-muted-foreground size-4 shrink-0" }), meta?.label] }), _jsx(CloseButton, { onClose: closeMobileTool, variant: "ghost" })] }) }), _jsxs("div", { className: "min-h-0 flex-1 overflow-hidden", children: [view === 'terminal' && (_jsx(SessionTerminalPanel, { sessionId: sessionId, projectId: projectId, projectSessionId: projectSessionId })), view === 'browser' && (_jsx(BrowserPanel, { tabId: sessionPreviewTabId(sessionId), projectId: projectId, projectSessionId: projectSessionId })), view === 'files' && (_jsx(SessionFilesExplorer, { chatSessionId: sessionId, projectId: projectId, projectSessionId: projectSessionId })), view === 'audit' && (_jsx(SessionAuditPanel, { projectId: projectId, projectSessionId: projectSessionId })), view === 'reminders' && (_jsx("div", { className: "h-full overflow-y-auto p-4", children: _jsx(SessionRemindersPanel, { projectId: projectId, projectSessionId: projectSessionId }) }))] })] }) }));
45
+ // Terminal, Browser and Files need the computer: while it boots, the drawer
46
+ // shows the wake status in their place.
47
+ const booting = !!useOptionalSessionPanel()?.booting &&
48
+ (view === 'terminal' || view === 'browser' || view === 'files');
49
+ return (_jsx(Drawer, { open: view !== null, onOpenChange: (next) => !next && closeMobileTool(), children: _jsxs(DrawerContent, { className: "flex h-[95dvh] max-h-[95dvh] min-h-[95dvh] flex-col overflow-hidden p-0", children: [_jsx(DrawerHeader, { className: "shrink-0 px-4 py-3 text-left", children: _jsxs(DrawerTitle, { className: "flex items-center justify-between gap-2 text-base", children: [_jsxs("span", { className: "flex items-center gap-2.5", children: [meta && _jsx(meta.Icon, { className: "text-muted-foreground size-4 shrink-0" }), meta?.label] }), _jsx(CloseButton, { onClose: closeMobileTool, variant: "ghost" })] }) }), _jsxs("div", { className: "min-h-0 flex-1 overflow-hidden", children: [booting && _jsx(SessionBootStatus, { projectId: projectId, sessionId: projectSessionId }), !booting && view === 'terminal' && (_jsx(SessionTerminalPanel, { sessionId: sessionId, projectId: projectId, projectSessionId: projectSessionId })), !booting && view === 'browser' && (_jsx(BrowserPanel, { tabId: sessionPreviewTabId(sessionId), projectId: projectId, projectSessionId: projectSessionId })), !booting && view === 'files' && (_jsx(SessionFilesExplorer, { chatSessionId: sessionId, projectId: projectId, projectSessionId: projectSessionId })), view === 'audit' && (_jsx(SessionAuditPanel, { projectId: projectId, projectSessionId: projectSessionId })), view === 'reminders' && (_jsx("div", { className: "h-full overflow-y-auto p-4", children: _jsx(SessionRemindersPanel, { projectId: projectId, projectSessionId: projectSessionId }) }))] })] }) }));
44
50
  }
@@ -8,15 +8,20 @@ import { Modal, ModalBody, ModalContent, ModalDescription, ModalHeader, ModalTit
8
8
  import { errorToast, successToast } from '../../primitives/toast.js';
9
9
  import { EmptyState } from '../../primitives/empty-state.js';
10
10
  import { ErrorState } from '../../primitives/error-state.js';
11
- import { approvalLauncherName, approvalRequestFromAction, } from '../prompts/session-approval-review.js';
11
+ import { approvalLauncherName, approvalRequestFromAction, auditPolicySet, } from '../prompts/session-approval-review.js';
12
12
  import { isPendingAction, relativeTime, riskTone, statusLabel, statusTone, useResolveApproval, useSessionAudit, useSessionAuditTimeline, } from './session-audit-shared.js';
13
13
  import { credentialVia } from './audit/audit-credential-label.js';
14
14
  import { useTranslations } from '../../i18n/index.js';
15
15
  import { useProjectSession } from '@kortix/sdk/react';
16
16
  import { CaretRightIcon, ShieldCheckIcon } from '@phosphor-icons/react';
17
17
  import { useMemo, useState } from 'react';
18
+ /** The policy set that decided a history row, if one did. */
19
+ function setNameOf(action) {
20
+ return auditPolicySet(action.result_summary)?.name ?? null;
21
+ }
18
22
  export function SessionAuditPanel({ projectId, projectSessionId, }) {
19
23
  const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
24
+ const tSets = useTranslations('connectorPolicySets');
20
25
  const approvalQuery = useSessionAudit(projectId, projectSessionId);
21
26
  const { data } = approvalQuery;
22
27
  const timelineQuery = useSessionAuditTimeline(projectId, projectSessionId, {
@@ -74,7 +79,9 @@ export function SessionAuditPanel({ projectId, projectSessionId, }) {
74
79
  : 'muted', size: "xs", className: "capitalize", children: event.outcome ?? 'recorded' })] }), _jsxs("p", { className: "text-muted-foreground mt-0.5 truncate text-xs", children: [credentialVia(event, (key) => tI18nComplete.raw(key)) ??
75
80
  event.authoritative_source ??
76
81
  event.source ??
77
- 'system', ' ', "\u00B7", ' ', relativeTime(event.occurred_at)] })] }), _jsx(CaretRightIcon, { className: "text-muted-foreground size-4 shrink-0" })] }) }, event.event_id))) }), timelineQuery.hasNextPage ? (_jsx("div", { className: "flex justify-center pt-1", children: _jsxs(Button, { size: "sm", variant: "outline", disabled: timelineQuery.isFetchingNextPage, onClick: () => void timelineQuery.fetchNextPage(), children: [timelineQuery.isFetchingNextPage ? _jsx(Loading, { className: "size-3.5" }) : null, tI18nComplete.raw('text96f2482de866')] }) })) : null] })) : null, history.length > 0 ? (_jsxs("section", { className: "space-y-3", children: [_jsx("h3", { className: "text-muted-foreground text-xs font-medium", children: tI18nComplete.raw('text0e7696009337') }), _jsx("ul", { className: "bg-popover overflow-hidden rounded-md border", children: history.map((action) => (_jsx("li", { className: "border-border border-b last:border-b-0", children: _jsxs("button", { type: "button", className: "hover:bg-primary/[0.03] flex min-h-12 w-full items-center gap-3 px-4 py-2 text-left transition-[background-color,transform] active:scale-[0.96]", onClick: () => setSelected(action), children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-1.5", children: [_jsx("code", { className: "text-foreground truncate font-mono text-sm", children: action.action }), action.risk ? (_jsx(Badge, { variant: riskTone(action.risk), size: "xs", className: "capitalize", children: action.risk })) : null, _jsx(Badge, { variant: statusTone(action.status), size: "xs", children: statusLabel(action.status) })] }), _jsxs("p", { className: "text-muted-foreground mt-0.5 truncate text-xs", children: [action.acted_by_email ?? 'agent', " \u00B7 ", relativeTime(action.at), action.resolved_by_email
82
+ 'system', ' ', "\u00B7", ' ', relativeTime(event.occurred_at)] })] }), _jsx(CaretRightIcon, { className: "text-muted-foreground size-4 shrink-0" })] }) }, event.event_id))) }), timelineQuery.hasNextPage ? (_jsx("div", { className: "flex justify-center pt-1", children: _jsxs(Button, { size: "sm", variant: "outline", disabled: timelineQuery.isFetchingNextPage, onClick: () => void timelineQuery.fetchNextPage(), children: [timelineQuery.isFetchingNextPage ? _jsx(Loading, { className: "size-3.5" }) : null, tI18nComplete.raw('text96f2482de866')] }) })) : null] })) : null, history.length > 0 ? (_jsxs("section", { className: "space-y-3", children: [_jsx("h3", { className: "text-muted-foreground text-xs font-medium", children: tI18nComplete.raw('text0e7696009337') }), _jsx("ul", { className: "bg-popover overflow-hidden rounded-md border", children: history.map((action) => (_jsx("li", { className: "border-border border-b last:border-b-0", children: _jsxs("button", { type: "button", className: "hover:bg-primary/[0.03] flex min-h-12 w-full items-center gap-3 px-4 py-2 text-left transition-[background-color,transform] active:scale-[0.96]", onClick: () => setSelected(action), children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-1.5", children: [_jsx("code", { className: "text-foreground truncate font-mono text-sm", children: action.action }), action.risk ? (_jsx(Badge, { variant: riskTone(action.risk), size: "xs", className: "capitalize", children: action.risk })) : null, _jsx(Badge, { variant: statusTone(action.status), size: "xs", children: statusLabel(action.status) })] }), _jsxs("p", { className: "text-muted-foreground mt-0.5 truncate text-xs", children: [action.acted_by_email ?? 'agent', " \u00B7 ", relativeTime(action.at), setNameOf(action)
83
+ ? ` · ${tSets('auditSet', { set: setNameOf(action) })}`
84
+ : '', action.resolved_by_email
78
85
  ? tI18nComplete('text0e16f24ee012', {
79
86
  value0: action.status === 'denied' ? 'denied' : 'approved',
80
87
  value1: action.resolved_by_email,
@@ -151,7 +151,7 @@ export function riskTone(risk) {
151
151
  }
152
152
  /** Terminal outcome of a gated action → badge tone. */
153
153
  export function statusTone(status) {
154
- if (status === 'ok')
154
+ if (status === 'ok' || status === 'approved')
155
155
  return 'success';
156
156
  if (status === 'denied' || status === 'error')
157
157
  return 'destructive';
@@ -164,6 +164,8 @@ export function statusLabel(status) {
164
164
  switch (status) {
165
165
  case 'ok':
166
166
  return 'Allowed';
167
+ case 'approved':
168
+ return 'Approved';
167
169
  case 'denied':
168
170
  return 'Denied';
169
171
  case 'error':