@kortix/ui 0.14.8 → 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 (528) hide show
  1. package/README.md +2 -2
  2. package/dist/_vendor/kortix-shared.js +63 -3
  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/space-slug.d.ts +37 -0
  7. package/dist/access/access/access-detail-shell.js +1 -1
  8. package/dist/access/access/principal-picker.d.ts +11 -0
  9. package/dist/access/access/principal-picker.js +3 -2
  10. package/dist/apps/app-preview-pool.d.ts +7 -2
  11. package/dist/apps/app-preview-pool.js +11 -5
  12. package/dist/apps/app-shared.d.ts +22 -15
  13. package/dist/apps/app-shared.js +37 -19
  14. package/dist/apps/index.d.ts +2 -2
  15. package/dist/apps/index.js +2 -2
  16. package/dist/artifacts/artifact-frame.d.ts +16 -0
  17. package/dist/artifacts/artifact-frame.js +51 -0
  18. package/dist/artifacts/artifact-session.d.ts +18 -0
  19. package/dist/artifacts/artifact-session.js +101 -0
  20. package/dist/artifacts/frame-policy.d.ts +30 -0
  21. package/dist/artifacts/frame-policy.js +61 -0
  22. package/dist/artifacts/index.d.ts +3 -0
  23. package/dist/artifacts/index.js +5 -0
  24. package/dist/browser/sandbox-browser-chrome.d.ts +4 -1
  25. package/dist/browser/sandbox-browser-chrome.js +2 -2
  26. package/dist/customize/agents/agent-grant-pages.d.ts +5 -1
  27. package/dist/customize/agents/agent-grant-pages.js +30 -4
  28. package/dist/customize/agents/agent-page.js +3 -1
  29. package/dist/customize/agents/agent-policy-sets.d.ts +43 -0
  30. package/dist/customize/agents/agent-policy-sets.js +72 -0
  31. package/dist/customize/agents/agent-triggers-section.js +2 -1
  32. package/dist/customize/connectors/add-mcp/add-mcp-server-dialog.d.ts +6 -1
  33. package/dist/customize/connectors/add-mcp/add-mcp-server-dialog.js +10 -4
  34. package/dist/customize/connectors/agent-access.d.ts +35 -0
  35. package/dist/customize/connectors/agent-access.js +77 -0
  36. package/dist/customize/connectors/catalog/browse-sections.d.ts +2 -29
  37. package/dist/customize/connectors/catalog/browse-sections.js +7 -74
  38. package/dist/customize/connectors/catalog/catalog-entry.d.ts +18 -37
  39. package/dist/customize/connectors/catalog/catalog-entry.js +28 -40
  40. package/dist/customize/connectors/catalog/connector-browse.d.ts +3 -32
  41. package/dist/customize/connectors/catalog/connector-browse.js +19 -50
  42. package/dist/customize/connectors/catalog/use-catalog.d.ts +20 -59
  43. package/dist/customize/connectors/catalog/use-catalog.js +48 -175
  44. package/dist/customize/connectors/connector-identity.d.ts +9 -11
  45. package/dist/customize/connectors/connector-identity.js +13 -42
  46. package/dist/customize/connectors/connector-moves-banner.d.ts +2 -1
  47. package/dist/customize/connectors/connector-moves-banner.js +4 -6
  48. package/dist/customize/connectors/connector-routes.d.ts +21 -9
  49. package/dist/customize/connectors/connector-routes.js +29 -20
  50. package/dist/customize/connectors/connectors-page.js +53 -82
  51. package/dist/customize/connectors/detail/app-page.js +226 -98
  52. package/dist/customize/connectors/detail/computer-app-page.d.ts +16 -0
  53. package/dist/customize/connectors/detail/computer-app-page.js +39 -0
  54. package/dist/customize/connectors/detail/connector-accounts.js +3 -1
  55. package/dist/customize/connectors/detail/connector-advanced-tools.d.ts +4 -1
  56. package/dist/customize/connectors/detail/connector-advanced-tools.js +2 -2
  57. package/dist/customize/connectors/detail/connector-agents.d.ts +14 -0
  58. package/dist/customize/connectors/detail/connector-agents.js +69 -0
  59. package/dist/customize/connectors/detail/connector-detail-tabs.js +2 -1
  60. package/dist/customize/connectors/detail/connector-move-row.d.ts +8 -5
  61. package/dist/customize/connectors/detail/connector-move-row.js +23 -14
  62. package/dist/customize/connectors/detail/connector-page.d.ts +4 -1
  63. package/dist/customize/connectors/detail/connector-page.js +14 -10
  64. package/dist/customize/connectors/detail/connector-policy-sets.d.ts +28 -0
  65. package/dist/customize/connectors/detail/connector-policy-sets.js +203 -0
  66. package/dist/customize/connectors/detail/connector-settings.d.ts +4 -1
  67. package/dist/customize/connectors/detail/connector-settings.js +7 -3
  68. package/dist/customize/connectors/detail/connector-status.d.ts +19 -6
  69. package/dist/customize/connectors/detail/connector-status.js +34 -10
  70. package/dist/customize/connectors/detail/connector-tabs.d.ts +4 -1
  71. package/dist/customize/connectors/detail/connector-tabs.js +8 -2
  72. package/dist/customize/connectors/detail/connector-tools.d.ts +3 -3
  73. package/dist/customize/connectors/detail/connector-tools.js +105 -48
  74. package/dist/customize/connectors/detail/email-inboxes.d.ts +43 -0
  75. package/dist/customize/connectors/detail/email-inboxes.js +184 -0
  76. package/dist/customize/connectors/detail/provider-info.d.ts +1 -1
  77. package/dist/customize/connectors/detail/provider-info.js +2 -2
  78. package/dist/customize/connectors/detail/status-badge.d.ts +1 -1
  79. package/dist/customize/connectors/detail/status-badge.js +4 -5
  80. package/dist/customize/connectors/detail/use-connector-detail.d.ts +6 -0
  81. package/dist/customize/connectors/detail/use-connector-detail.js +14 -4
  82. package/dist/customize/connectors/install/install-dialog.d.ts +23 -0
  83. package/dist/customize/connectors/install/install-dialog.js +40 -0
  84. package/dist/customize/connectors/install/install.d.ts +13 -2
  85. package/dist/customize/connectors/install/install.js +9 -4
  86. package/dist/customize/connectors/install/use-install.d.ts +19 -2
  87. package/dist/customize/connectors/install/use-install.js +65 -37
  88. package/dist/customize/connectors/install/way-kind.d.ts +5 -0
  89. package/dist/customize/connectors/install/way-kind.js +16 -0
  90. package/dist/customize/connectors/provider-label.d.ts +2 -1
  91. package/dist/customize/connectors/provider-label.js +13 -3
  92. package/dist/customize/connectors/tools/pattern-rule-draft.d.ts +4 -0
  93. package/dist/customize/connectors/tools/pattern-rule-draft.js +12 -3
  94. package/dist/customize/connectors/tools/policy-sets.d.ts +27 -0
  95. package/dist/customize/connectors/tools/policy-sets.js +41 -0
  96. package/dist/customize/connectors/tools/tool-groups.d.ts +32 -9
  97. package/dist/customize/connectors/tools/tool-groups.js +78 -16
  98. package/dist/customize/connectors/tools/tool-policy-control.d.ts +11 -10
  99. package/dist/customize/connectors/tools/tool-policy-control.js +15 -16
  100. package/dist/customize/connectors/tools/tool-policy-labels.d.ts +6 -5
  101. package/dist/customize/connectors/tools/tool-policy-labels.js +17 -16
  102. package/dist/customize/connectors/tools/tool-policy.d.ts +50 -4
  103. package/dist/customize/connectors/tools/tool-policy.js +74 -8
  104. package/dist/customize/connectors/use-agent-access.d.ts +85 -0
  105. package/dist/customize/connectors/use-agent-access.js +72 -0
  106. package/dist/customize/migrate-to-v2/index.d.ts +1 -2
  107. package/dist/customize/migrate-to-v2/index.js +1 -2
  108. package/dist/customize/migrate-to-v2/migration-prompt.d.ts +12 -25
  109. package/dist/customize/migrate-to-v2/migration-prompt.js +34 -236
  110. package/dist/customize/migrate-to-v2/upgrade-defs.d.ts +1 -1
  111. package/dist/customize/migrate-to-v2/upgrade-defs.js +7 -6
  112. package/dist/customize/migrate-to-v2/upgrade-view.js +7 -7
  113. package/dist/customize/migrate-to-v2/use-run-upgrade.d.ts +3 -3
  114. package/dist/customize/providers/provider-accordion.js +17 -2
  115. package/dist/customize/sections/component/channel-access-panel.d.ts +16 -0
  116. package/dist/customize/sections/component/channel-access-panel.js +146 -0
  117. package/dist/customize/sections/component/channel-connect-hero.d.ts +3 -2
  118. package/dist/customize/sections/component/channel-connect-hero.js +3 -2
  119. package/dist/customize/sections/component/channel-hero-frame.d.ts +31 -0
  120. package/dist/customize/sections/component/channel-hero-frame.js +40 -0
  121. package/dist/customize/sections/component/channel-mocks.d.ts +6 -0
  122. package/dist/customize/sections/component/channel-mocks.js +46 -0
  123. package/dist/customize/sections/component/channel-row.d.ts +13 -3
  124. package/dist/customize/sections/component/channel-row.js +10 -4
  125. package/dist/customize/sections/component/email-connect-form.d.ts +27 -0
  126. package/dist/customize/sections/component/email-connect-form.js +183 -0
  127. package/dist/customize/sections/component/slack-connect-card.d.ts +7 -0
  128. package/dist/customize/sections/component/slack-connect-card.js +2 -3
  129. package/dist/customize/sections/component/teams-connect-card.d.ts +7 -0
  130. package/dist/customize/sections/component/teams-connect-card.js +2 -3
  131. package/dist/customize/sections/component/telegram-channel-row.js +16 -25
  132. package/dist/customize/sections/connectors-view.d.ts +1 -15
  133. package/dist/customize/sections/connectors-view.js +81 -314
  134. package/dist/customize/sections/view/agent-editor-catalog.js +5 -0
  135. package/dist/customize/sections/view/channels-view.d.ts +5 -1
  136. package/dist/customize/sections/view/channels-view.js +61 -75
  137. package/dist/customize/sections/view/gateway/gateway-overview.js +10 -2
  138. package/dist/customize/settings/tabs/experimental-tab.js +35 -16
  139. package/dist/customize/shared/catalog/catalog-empty-state.d.ts +1 -12
  140. package/dist/customize/shared/catalog/catalog-empty-state.js +3 -3
  141. package/dist/customize/shared/channels-switch-dialog.d.ts +18 -0
  142. package/dist/customize/shared/channels-switch-dialog.js +30 -0
  143. package/dist/customize/shared/feature-gate-screen.js +27 -9
  144. package/dist/customize/shared/use-customize-prefetch.d.ts +2 -3
  145. package/dist/customize/shared/use-customize-prefetch.js +9 -27
  146. package/dist/customize/triggers/schedule/post-to-field.d.ts +18 -0
  147. package/dist/customize/triggers/schedule/post-to-field.js +49 -0
  148. package/dist/customize/triggers/schedule/schedule-copy.d.ts +10 -6
  149. package/dist/customize/triggers/schedule/schedule-copy.js +42 -11
  150. package/dist/customize/triggers/schedule/schedule-detail-sheet.js +2 -1
  151. package/dist/customize/triggers/schedule/trigger-composer-logic.d.ts +22 -0
  152. package/dist/customize/triggers/schedule/trigger-composer-logic.js +25 -0
  153. package/dist/customize/triggers/schedule/trigger-composer.d.ts +5 -0
  154. package/dist/customize/triggers/schedule/trigger-composer.js +23 -14
  155. package/dist/customize/triggers/schedule/trigger-edit-logic.js +3 -0
  156. package/dist/customize/triggers/schedule/trigger-filter.js +1 -1
  157. package/dist/customize/triggers/schedule/trigger-runs-logic.d.ts +2 -2
  158. package/dist/customize/triggers/schedule/trigger-runs-panel.js +1 -0
  159. package/dist/customize/triggers/schedule/trigger-toast.js +2 -1
  160. package/dist/customize/triggers/schedule-view.js +5 -2
  161. package/dist/files/index.d.ts +1 -0
  162. package/dist/files/index.js +1 -0
  163. package/dist/files/project/change-request-recovery.d.ts +1 -26
  164. package/dist/files/project/change-request-recovery.js +1 -59
  165. package/dist/files/project/components/change-request-detail-dialog.js +13 -3
  166. package/dist/files/project/components/drive-explorer.js +15 -15
  167. package/dist/files/project/components/drive-toolbar.d.ts +16 -2
  168. package/dist/files/project/components/drive-toolbar.js +14 -5
  169. package/dist/files/project/hooks/use-change-request-recovery.js +3 -19
  170. package/dist/files/project/hooks/use-change-requests.d.ts +1 -0
  171. package/dist/files/project/hooks/use-change-requests.js +11 -2
  172. package/dist/files/renderers/image-frame.d.ts +46 -0
  173. package/dist/files/renderers/image-frame.js +59 -0
  174. package/dist/files/renderers/image-renderer.d.ts +11 -1
  175. package/dist/files/renderers/image-renderer.js +13 -3
  176. package/dist/files/renderers/pdf/pdf-clipboard.d.ts +2 -0
  177. package/dist/files/renderers/pdf/pdf-clipboard.js +21 -0
  178. package/dist/files/renderers/pdf/pdf-viewer.js +4 -2
  179. package/dist/files/renderers/show-content-renderer.d.ts +9 -1
  180. package/dist/files/renderers/show-content-renderer.js +56 -14
  181. package/dist/files/runtime/file-source.js +2 -0
  182. package/dist/files/runtime/hooks/use-binary-blob.d.ts +10 -1
  183. package/dist/files/runtime/hooks/use-binary-blob.js +10 -4
  184. package/dist/files/runtime/hooks/use-shared-image.d.ts +41 -0
  185. package/dist/files/runtime/hooks/use-shared-image.js +177 -0
  186. package/dist/files/viewer/file-content-renderer.d.ts +22 -1
  187. package/dist/files/viewer/file-content-renderer.js +50 -7
  188. package/dist/files/viewer/file-header.d.ts +7 -3
  189. package/dist/files/viewer/file-header.js +20 -11
  190. package/dist/files/viewer/file-preview-modal.d.ts +1 -1
  191. package/dist/files/viewer/file-preview-modal.js +10 -22
  192. package/dist/files/viewer/file-source.d.ts +13 -0
  193. package/dist/files/viewer/use-file-content-state.d.ts +2 -0
  194. package/dist/files/viewer/use-file-content-state.js +28 -10
  195. package/dist/files/viewer/viewer-actions.d.ts +3 -1
  196. package/dist/files/viewer/viewer-actions.js +2 -2
  197. package/dist/hooks/use-media-query.d.ts +1 -0
  198. package/dist/hooks/use-mobile.d.ts +5 -0
  199. package/dist/hooks/use-mobile.js +8 -0
  200. package/dist/i18n/en.d.ts +873 -85
  201. package/dist/i18n/en.js +888 -100
  202. package/dist/i18n/ui-catalog/localize-ui-catalog.js +4 -0
  203. package/dist/i18n/ui-catalog/remaining-ui-translation-keys.generated.js +15 -3
  204. package/dist/index.d.ts +2 -2
  205. package/dist/index.js +2 -2
  206. package/dist/internal/account-hub/account-settings-sidebar.js +1 -1
  207. package/dist/internal/account-hub/hub-sheet.d.ts +9 -1
  208. package/dist/internal/account-hub/hub-sheet.js +21 -5
  209. package/dist/internal/account-hub/sections.d.ts +1 -1
  210. package/dist/internal/account-hub/sections.js +2 -1
  211. package/dist/internal/auth/auth-card-shell.js +3 -3
  212. package/dist/internal/components/agent-mark.js +5 -2
  213. package/dist/internal/connector-logo/connector-logo-source.d.ts +63 -0
  214. package/dist/internal/connector-logo/connector-logo-source.js +48 -0
  215. package/dist/internal/connector-logo/connector-logo.d.ts +39 -0
  216. package/dist/internal/connector-logo/connector-logo.js +56 -0
  217. package/dist/internal/connector-logo/connector-mark-files.d.ts +11 -0
  218. package/dist/internal/connector-logo/connector-mark-files.js +35 -0
  219. package/dist/internal/files/file-read-retry.d.ts +13 -0
  220. package/dist/internal/files/file-read-retry.js +23 -3
  221. package/dist/internal/files/session-drive-files.d.ts +5 -1
  222. package/dist/internal/files/session-drive-files.js +7 -2
  223. package/dist/internal/hooks/channels/use-channels-installations.d.ts +32 -5
  224. package/dist/internal/hooks/channels/use-channels-installations.js +55 -7
  225. package/dist/internal/hooks/channels/use-email-inboxes.d.ts +19 -0
  226. package/dist/internal/hooks/channels/use-email-inboxes.js +48 -0
  227. package/dist/internal/hooks/connectors/use-add-account.js +1 -1
  228. package/dist/internal/hooks/index.d.ts +1 -1
  229. package/dist/internal/hooks/index.js +1 -1
  230. package/dist/internal/hooks/projects/use-new-project-session.d.ts +9 -0
  231. package/dist/internal/hooks/projects/use-new-project-session.js +28 -12
  232. package/dist/internal/hooks/use-auto-scroll.d.ts +8 -1
  233. package/dist/internal/hooks/use-auto-scroll.js +4 -4
  234. package/dist/internal/icons/telegram.d.ts +5 -0
  235. package/dist/internal/icons/telegram.js +6 -1
  236. package/dist/internal/layout/nav-hover-card.d.ts +35 -0
  237. package/dist/internal/layout/nav-hover-card.js +84 -0
  238. package/dist/internal/layout/project-nav-row.d.ts +3 -1
  239. package/dist/internal/layout/project-nav-row.js +3 -2
  240. package/dist/internal/layout/project-page-header.d.ts +4 -2
  241. package/dist/internal/layout/project-page-header.js +4 -3
  242. package/dist/internal/layout/project-settings-nav.js +59 -2
  243. package/dist/internal/lib/browser-error-noise.d.ts +1 -1
  244. package/dist/internal/lib/browser-error-noise.js +1 -1
  245. package/dist/internal/lib/browser-noise/rules/injected-scripts.d.ts +7 -0
  246. package/dist/internal/lib/browser-noise/rules/injected-scripts.js +15 -0
  247. package/dist/internal/lib/manifest-version.d.ts +1 -1
  248. package/dist/internal/lib/manifest-version.js +2 -2
  249. package/dist/internal/lib/memory-href.d.ts +16 -0
  250. package/dist/internal/lib/memory-href.js +46 -0
  251. package/dist/internal/lib/use-project-feature-flags.js +9 -9
  252. package/dist/internal/lib/utils/heic-convert.d.ts +1 -1
  253. package/dist/internal/lib/utils/heic-convert.js +3 -4
  254. package/dist/internal/lib/web-notifications.d.ts +20 -0
  255. package/dist/internal/lib/web-notifications.js +48 -4
  256. package/dist/internal/notifications/notification-bell.d.ts +4 -1
  257. package/dist/internal/notifications/notification-bell.js +2 -2
  258. package/dist/internal/selection/selection-bar.d.ts +2 -1
  259. package/dist/internal/selection/selection-bar.js +1 -1
  260. package/dist/internal/stores/file-preview-store.d.ts +29 -2
  261. package/dist/internal/stores/file-preview-store.js +19 -1
  262. package/dist/internal/stores/kortix-computer-store.js +3 -0
  263. package/dist/internal/stores/sidebar-nav-store.d.ts +1 -1
  264. package/dist/internal/stores/sidebar-nav-store.js +3 -1
  265. package/dist/lib/routes.d.ts +13 -1
  266. package/dist/lib/routes.js +13 -0
  267. package/dist/markdown/index.d.ts +2 -1
  268. package/dist/markdown/index.js +2 -1
  269. package/dist/markdown/setup-links/approval-decision.d.ts +1 -0
  270. package/dist/markdown/setup-links/approval-decision.js +6 -2
  271. package/dist/markdown/setup-links/connector-handshake.d.ts +3 -1
  272. package/dist/markdown/setup-links/connector-handshake.js +12 -10
  273. package/dist/markdown/setup-links/secret-intake-form.d.ts +0 -10
  274. package/dist/markdown/setup-links/secret-intake-form.js +1 -1
  275. package/dist/markdown/setup-links/show-connect-hero.d.ts +28 -0
  276. package/dist/markdown/setup-links/show-connect-hero.js +91 -0
  277. package/dist/markdown/unified-markdown.js +5 -5
  278. package/dist/primitives/badge.d.ts +1 -1
  279. package/dist/primitives/badge.js +2 -0
  280. package/dist/primitives/disclosure.js +14 -2
  281. package/dist/primitives/empty-art.d.ts +12 -0
  282. package/dist/primitives/empty-art.js +11 -0
  283. package/dist/primitives/mermaid-renderer.d.ts +2 -0
  284. package/dist/primitives/mermaid-renderer.js +21 -15
  285. package/dist/primitives/resizable.js +6 -1
  286. package/dist/primitives/resize-seam.d.ts +11 -0
  287. package/dist/primitives/resize-seam.js +12 -0
  288. package/dist/primitives/sidebar-panel.js +4 -7
  289. package/dist/primitives/tabs.d.ts +14 -1
  290. package/dist/primitives/tabs.js +1 -1
  291. package/dist/providers/ui-provider.d.ts +9 -0
  292. package/dist/session/composer/ComposerAboveCard.d.ts +1 -1
  293. package/dist/session/composer/ComposerAboveCard.js +2 -2
  294. package/dist/session/composer/ComposerCard.d.ts +1 -1
  295. package/dist/session/composer/ComposerCard.js +3 -3
  296. package/dist/session/composer/agent-selector.d.ts +13 -1
  297. package/dist/session/composer/agent-selector.js +25 -5
  298. package/dist/session/composer/composer-agent-access.d.ts +15 -0
  299. package/dist/session/composer/composer-agent-access.js +27 -0
  300. package/dist/session/composer/composer-chat-input.d.ts +8 -2
  301. package/dist/session/composer/composer-chat-input.js +8 -6
  302. package/dist/session/composer/composer-logic.d.ts +16 -0
  303. package/dist/session/composer/composer-logic.js +12 -0
  304. package/dist/session/composer/composer-underbar.d.ts +3 -1
  305. package/dist/session/composer/composer-underbar.js +4 -3
  306. package/dist/session/composer/composer.d.ts +15 -1
  307. package/dist/session/composer/composer.js +19 -1
  308. package/dist/session/composer/draft/composer-draft.d.ts +6 -2
  309. package/dist/session/composer/draft/composer-draft.js +5 -1
  310. package/dist/session/composer/reasoning-effort-selector.js +1 -1
  311. package/dist/session/models/chatgpt-connection-button.d.ts +11 -0
  312. package/dist/session/models/chatgpt-connection-button.js +54 -0
  313. package/dist/session/models/model-selector.js +5 -2
  314. package/dist/session/models/use-model-connection-gate.d.ts +5 -5
  315. package/dist/session/models/use-model-connection-gate.js +5 -5
  316. package/dist/session/outcomes/jump-to-outcome.d.ts +10 -0
  317. package/dist/session/outcomes/jump-to-outcome.js +11 -0
  318. package/dist/session/outcomes/session-outcomes-bridge.d.ts +14 -0
  319. package/dist/session/outcomes/session-outcomes-bridge.js +12 -0
  320. package/dist/session/outcomes/session-outcomes-provider.d.ts +3 -1
  321. package/dist/session/outcomes/session-outcomes-provider.js +33 -3
  322. package/dist/session/panel/easy/app-preview.d.ts +10 -0
  323. package/dist/session/panel/easy/app-preview.js +31 -12
  324. package/dist/session/panel/easy/change-requests-card.d.ts +7 -0
  325. package/dist/session/panel/easy/change-requests-card.js +17 -0
  326. package/dist/session/panel/easy/easy-panel-logic.js +7 -1
  327. package/dist/session/panel/easy/easy-panel.js +5 -2
  328. package/dist/session/panel/easy/file-preview.js +1 -1
  329. package/dist/session/panel/easy/outputs-card.d.ts +2 -1
  330. package/dist/session/panel/easy/outputs-card.js +3 -2
  331. package/dist/session/panel/mobile-tool-drawer.js +7 -1
  332. package/dist/session/panel/session-audit-panel.js +9 -2
  333. package/dist/session/panel/session-detail-panel.js +9 -3
  334. package/dist/session/panel/session-files-explorer.d.ts +9 -0
  335. package/dist/session/panel/session-files-explorer.js +12 -3
  336. package/dist/session/panel/session-panel-provider.d.ts +15 -1
  337. package/dist/session/panel/session-panel-provider.js +32 -7
  338. package/dist/session/panel/shared/derive-panels.d.ts +8 -1
  339. package/dist/session/panel/shared/derive-panels.js +12 -2
  340. package/dist/session/panel/shared/output-priority.js +2 -0
  341. package/dist/session/participants/session-participants.d.ts +5 -1
  342. package/dist/session/participants/session-participants.js +9 -2
  343. package/dist/session/prompts/approval-request.d.ts +5 -0
  344. package/dist/session/prompts/approval-request.js +7 -1
  345. package/dist/session/prompts/session-approval-review.d.ts +9 -0
  346. package/dist/session/prompts/session-approval-review.js +18 -0
  347. package/dist/session/status/session-error-banner.js +2 -49
  348. package/dist/session/status/session-starting-loader.d.ts +14 -2
  349. package/dist/session/status/session-starting-loader.js +16 -4
  350. package/dist/session/thread/after-first-prompt.d.ts +7 -0
  351. package/dist/session/thread/after-first-prompt.js +8 -0
  352. package/dist/session/thread/detect-command.d.ts +12 -0
  353. package/dist/session/thread/detect-command.js +20 -0
  354. package/dist/session/thread/session-chat.d.ts +3 -1
  355. package/dist/session/thread/session-chat.js +377 -252
  356. package/dist/session/thread/session-thread.d.ts +3 -1
  357. package/dist/session/thread/session-thread.js +9 -2
  358. package/dist/session/thread/thread-boot-rows.d.ts +36 -0
  359. package/dist/session/thread/thread-boot-rows.js +89 -0
  360. package/dist/session/thread/transcript-rows.d.ts +31 -0
  361. package/dist/session/thread/transcript-rows.js +3 -0
  362. package/dist/session/thread/transcript.d.ts +0 -9
  363. package/dist/session/thread/transcript.js +104 -19
  364. package/dist/session/tool/shared/infrastructure-contexts.d.ts +28 -0
  365. package/dist/session/tool/shared/infrastructure-contexts.js +31 -3
  366. package/dist/session/tool/tool-part-renderer.d.ts +5 -4
  367. package/dist/session/tool/tool-part-renderer.js +8 -3
  368. package/dist/session/tool/tools/bash-tool.js +7 -6
  369. package/dist/session/tool/tools/channel-send-card.d.ts +1 -2
  370. package/dist/session/tool/tools/channel-send.d.ts +2 -1
  371. package/dist/session/tool/tools/codemode-tool.js +1 -1
  372. package/dist/session/tool/tools/connector-tools.js +1 -1
  373. package/dist/session/tool/tools/image-gen-tool.d.ts +1 -1
  374. package/dist/session/tool/tools/image-gen-tool.js +240 -53
  375. package/dist/session/tool/tools/show-tool.js +19 -8
  376. package/dist/session/turn/channel-brand.d.ts +8 -3
  377. package/dist/session/turn/channel-brand.js +20 -4
  378. package/dist/session/turn/message-author.d.ts +8 -0
  379. package/dist/session/turn/message-author.js +24 -0
  380. package/dist/session/turn/message-row.d.ts +52 -0
  381. package/dist/session/turn/message-row.js +44 -0
  382. package/dist/session/turn/plan-anchor.d.ts +1 -1
  383. package/dist/session/turn/plan-anchor.js +1 -1
  384. package/dist/session/turn/user-message.d.ts +7 -1
  385. package/dist/session/turn/user-message.js +21 -7
  386. package/dist/styles.css +1 -1
  387. package/dist/workspace/home/access-requests-bell.d.ts +9 -2
  388. package/dist/workspace/home/access-requests-bell.js +20 -6
  389. package/dist/workspace/home/first-chat.d.ts +8 -21
  390. package/dist/workspace/home/first-chat.js +22 -72
  391. package/dist/workspace/index.d.ts +6 -0
  392. package/dist/workspace/index.js +6 -0
  393. package/dist/workspace/layout/project-home.d.ts +14 -2
  394. package/dist/workspace/layout/project-home.js +60 -21
  395. package/dist/workspace/layout/use-project-home-send.d.ts +9 -1
  396. package/dist/workspace/layout/use-project-home-send.js +82 -3
  397. package/dist/workspace/memory/body-doc.d.ts +17 -0
  398. package/dist/workspace/memory/body-doc.js +208 -0
  399. package/dist/workspace/memory/body-extensions.d.ts +38 -0
  400. package/dist/workspace/memory/body-extensions.js +103 -0
  401. package/dist/workspace/memory/company-memory-page.d.ts +8 -0
  402. package/dist/workspace/memory/company-memory-page.js +16 -0
  403. package/dist/workspace/memory/memory-all.d.ts +20 -0
  404. package/dist/workspace/memory/memory-all.js +27 -0
  405. package/dist/workspace/memory/memory-body.d.ts +19 -0
  406. package/dist/workspace/memory/memory-body.js +139 -0
  407. package/dist/workspace/memory/memory-empty.d.ts +13 -0
  408. package/dist/workspace/memory/memory-empty.js +28 -0
  409. package/dist/workspace/memory/memory-history.d.ts +27 -0
  410. package/dist/workspace/memory/memory-history.js +108 -0
  411. package/dist/workspace/memory/memory-labels.d.ts +16 -0
  412. package/dist/workspace/memory/memory-labels.js +47 -0
  413. package/dist/workspace/memory/memory-page-list.d.ts +34 -0
  414. package/dist/workspace/memory/memory-page-list.js +156 -0
  415. package/dist/workspace/memory/memory-reader.d.ts +58 -0
  416. package/dist/workspace/memory/memory-reader.js +123 -0
  417. package/dist/workspace/memory/memory-view.d.ts +21 -0
  418. package/dist/workspace/memory/memory-view.js +124 -0
  419. package/dist/workspace/memory/remember-popover.d.ts +19 -0
  420. package/dist/workspace/memory/remember-popover.js +61 -0
  421. package/dist/workspace/memory/remember-this.d.ts +12 -0
  422. package/dist/workspace/memory/remember-this.js +89 -0
  423. package/dist/workspace/memory/source-mark.d.ts +18 -0
  424. package/dist/workspace/memory/source-mark.js +79 -0
  425. package/dist/workspace/memory/used-memory-chip.d.ts +14 -0
  426. package/dist/workspace/memory/used-memory-chip.js +61 -0
  427. package/dist/workspace/new/advanced-fields.d.ts +2 -1
  428. package/dist/workspace/new/advanced-fields.js +2 -2
  429. package/dist/workspace/new/source-param.d.ts +1 -1
  430. package/dist/workspace/new/source-param.js +3 -1
  431. package/dist/workspace/new/use-create-workspace.d.ts +8 -10
  432. package/dist/workspace/new/use-create-workspace.js +3 -3
  433. package/dist/workspace/projects/onboarding/app-logo.d.ts +7 -2
  434. package/dist/workspace/projects/onboarding/app-logo.js +6 -13
  435. package/dist/workspace/projects/policies-panel.js +5 -3
  436. package/dist/workspace/review/review-actions.d.ts +4 -2
  437. package/dist/workspace/review/review-actions.js +8 -2
  438. package/dist/workspace/review/review-center.js +11 -7
  439. package/dist/workspace/review/review-detail.d.ts +10 -0
  440. package/dist/workspace/review/review-detail.js +101 -13
  441. package/dist/workspace/saved-session-skeleton.d.ts +2 -2
  442. package/dist/workspace/saved-session-skeleton.js +3 -3
  443. package/dist/workspace/session-workspace.js +15 -13
  444. package/dist/workspace/sessions/project-sessions-view.js +3 -2
  445. package/dist/workspace/sessions/sessions-toolbar.d.ts +3 -1
  446. package/dist/workspace/sessions/sessions-toolbar.js +2 -2
  447. package/dist/workspace/sidebar/footer/project-apps-nav.d.ts +5 -0
  448. package/dist/workspace/sidebar/footer/project-apps-nav.js +41 -2
  449. package/dist/workspace/sidebar/footer/project-artifacts-nav.d.ts +6 -0
  450. package/dist/workspace/sidebar/footer/project-artifacts-nav.js +22 -0
  451. package/dist/workspace/sidebar/footer/project-manifest-upgrade-alert.js +13 -13
  452. package/dist/workspace/sidebar/footer/project-memory-nav.d.ts +7 -0
  453. package/dist/workspace/sidebar/footer/project-memory-nav.js +19 -0
  454. package/dist/workspace/sidebar/nav-row-meta.js +14 -2
  455. package/dist/workspace/sidebar/project-nav-items.js +3 -0
  456. package/dist/workspace/sidebar/project-session-list.js +68 -56
  457. package/dist/workspace/sidebar/project-sidebar.js +9 -2
  458. package/dist/workspace/sidebar/project-spaces-nav.d.ts +8 -0
  459. package/dist/workspace/sidebar/project-spaces-nav.js +69 -0
  460. package/dist/workspace/sidebar/session-group-order.d.ts +9 -0
  461. package/dist/workspace/sidebar/session-group-order.js +25 -0
  462. package/dist/workspace/sidebar/session-group-sections.d.ts +62 -0
  463. package/dist/workspace/sidebar/session-group-sections.js +267 -0
  464. package/dist/workspace/sidebar/session-list-chrome.d.ts +28 -0
  465. package/dist/workspace/sidebar/session-list-chrome.js +50 -0
  466. package/dist/workspace/spaces/channel-glyph.d.ts +5 -0
  467. package/dist/workspace/spaces/channel-glyph.js +6 -0
  468. package/dist/workspace/spaces/channel-setup.d.ts +16 -0
  469. package/dist/workspace/spaces/channel-setup.js +105 -0
  470. package/dist/workspace/spaces/channels-onboarding.d.ts +13 -0
  471. package/dist/workspace/spaces/channels-onboarding.js +37 -0
  472. package/dist/workspace/spaces/create-channel-dialog.d.ts +16 -0
  473. package/dist/workspace/spaces/create-channel-dialog.js +158 -0
  474. package/dist/workspace/spaces/private-channels-not-in.d.ts +9 -0
  475. package/dist/workspace/spaces/private-channels-not-in.js +69 -0
  476. package/dist/workspace/spaces/space-agents.d.ts +10 -0
  477. package/dist/workspace/spaces/space-agents.js +10 -0
  478. package/dist/workspace/spaces/space-details-dialog.d.ts +20 -0
  479. package/dist/workspace/spaces/space-details-dialog.js +176 -0
  480. package/dist/workspace/spaces/space-link-label.d.ts +49 -0
  481. package/dist/workspace/spaces/space-link-label.js +73 -0
  482. package/dist/workspace/spaces/space-links.d.ts +19 -0
  483. package/dist/workspace/spaces/space-links.js +230 -0
  484. package/dist/workspace/spaces/space-members.d.ts +46 -0
  485. package/dist/workspace/spaces/space-members.js +182 -0
  486. package/dist/workspace/spaces/space-roster.d.ts +15 -0
  487. package/dist/workspace/spaces/space-roster.js +44 -0
  488. package/dist/workspace/spaces/space-threads-tab.d.ts +56 -0
  489. package/dist/workspace/spaces/space-threads-tab.js +156 -0
  490. package/dist/workspace/spaces/space-timeline-view.d.ts +254 -0
  491. package/dist/workspace/spaces/space-timeline-view.js +235 -0
  492. package/dist/workspace/spaces/space-timeline.d.ts +106 -0
  493. package/dist/workspace/spaces/space-timeline.js +183 -0
  494. package/dist/workspace/spaces/space-triggers.d.ts +13 -0
  495. package/dist/workspace/spaces/space-triggers.js +78 -0
  496. package/dist/workspace/spaces/space-view.d.ts +37 -0
  497. package/dist/workspace/spaces/space-view.js +436 -0
  498. package/package.json +27 -36
  499. package/skills/kortix-ui/SKILL.md +3 -3
  500. package/skills/kortix-ui/references/custom-dashboard.md +3 -3
  501. package/skills/kortix-ui/references/modules.md +28 -4
  502. package/skills/kortix-ui/references/theming.md +1 -1
  503. package/dist/customize/connectors/catalog/merge-search.d.ts +0 -10
  504. package/dist/customize/connectors/catalog/merge-search.js +0 -26
  505. package/dist/customize/connectors/detail/find-easy-connect-app.d.ts +0 -29
  506. package/dist/customize/connectors/detail/find-easy-connect-app.js +0 -22
  507. package/dist/customize/migrate-to-v2/use-migrate-to-v2.d.ts +0 -9
  508. package/dist/customize/migrate-to-v2/use-migrate-to-v2.js +0 -24
  509. package/dist/customize/sections/connector-connection-header.d.ts +0 -36
  510. package/dist/customize/sections/connector-connection-header.js +0 -33
  511. package/dist/customize/sections/connector-connection-modal.d.ts +0 -34
  512. package/dist/customize/sections/connector-connection-modal.js +0 -72
  513. package/dist/customize/sections/discover-catalogue-card.d.ts +0 -19
  514. package/dist/customize/sections/discover-catalogue-card.js +0 -26
  515. package/dist/customize/sections/discover-catalogue-detail.d.ts +0 -15
  516. package/dist/customize/sections/discover-catalogue-detail.js +0 -24
  517. package/dist/customize/sections/discover-catalogue.d.ts +0 -17
  518. package/dist/customize/sections/discover-catalogue.js +0 -132
  519. package/dist/customize/sections/llm-provider/provider-access-menu.d.ts +0 -10
  520. package/dist/customize/sections/llm-provider/provider-access-menu.js +0 -23
  521. package/dist/files/project/components/drive-empty-art.d.ts +0 -2
  522. package/dist/files/project/components/drive-empty-art.js +0 -5
  523. package/dist/internal/hooks/use-media-query.d.ts +0 -2
  524. package/dist/internal/share/public-share-link-button.d.ts +0 -14
  525. package/dist/internal/share/public-share-link-button.js +0 -17
  526. package/dist/markdown/setup-links/app-credentials-form.d.ts +0 -12
  527. package/dist/markdown/setup-links/app-credentials-form.js +0 -115
  528. /package/dist/{internal/hooks → hooks}/use-media-query.js +0 -0
@@ -2,6 +2,10 @@ import type { ComponentType, ReactNode, Dispatch, SetStateAction, MutableRefObje
2
2
  import type { FileContent } from './file-source.js';
3
3
  interface FileHeaderProps {
4
4
  showHeader: boolean;
5
+ /** A host toolbar to render into (`FilePreviewModal`). The host owns the
6
+ * name, path, Download and the Markdown toggle, so only the edit state and
7
+ * the HTML/JSON view toggles go there. */
8
+ headerSlot?: HTMLElement | null;
5
9
  Breadcrumbs: ComponentType<{
6
10
  filePath: string;
7
11
  }> | undefined;
@@ -30,8 +34,8 @@ interface FileHeaderProps {
30
34
  handleDownload: () => Promise<void>;
31
35
  blobUrl: string | null;
32
36
  rawBlob: Blob | null;
33
- tI18nHardcoded: ReturnType<typeof import("../../i18n/index.js").useTranslations>;
34
- tHardcodedUi: ReturnType<typeof import("../../i18n/index.js").useTranslations>;
37
+ tI18nHardcoded: ReturnType<typeof import('../../i18n/index.js').useTranslations>;
38
+ tHardcodedUi: ReturnType<typeof import('../../i18n/index.js').useTranslations>;
35
39
  }
36
- export declare function FileHeader({ showHeader, Breadcrumbs, filePath, readOnly, hasUnsavedChanges, saveFlash, fileDiagErrorCount, fileDiagWarningCount, fileContent, isSaving, handleSave, latestContentRef, discardLabel, handleDiscard, isHtmlFile, isHtmlPreview, setIsHtmlPreview, isJsonFile, isJsonTreeView, setIsJsonTreeView, hasPreviewToggle, isMarkdownPreview, setIsMarkdownPreview, headerActions, handleDownload, blobUrl, rawBlob, tI18nHardcoded, tHardcodedUi }: FileHeaderProps): import("react").JSX.Element;
40
+ export declare function FileHeader({ showHeader, headerSlot, Breadcrumbs, filePath, readOnly, hasUnsavedChanges, saveFlash, fileDiagErrorCount, fileDiagWarningCount, fileContent, isSaving, handleSave, latestContentRef, discardLabel, handleDiscard, isHtmlFile, isHtmlPreview, setIsHtmlPreview, isJsonFile, isJsonTreeView, setIsJsonTreeView, hasPreviewToggle, isMarkdownPreview, setIsMarkdownPreview, headerActions, handleDownload, blobUrl, rawBlob, tI18nHardcoded, tHardcodedUi, }: FileHeaderProps): import("react").JSX.Element | null;
37
41
  export {};
@@ -6,16 +6,25 @@ import Hint from '../../primitives/hint.js';
6
6
  import Loading from '../../primitives/loading.js';
7
7
  import { StatusDot } from '../../primitives/status.js';
8
8
  import { cn } from '../../lib/utils.js';
9
- import { WarningIcon as AlertTriangle, BracketsCurlyIcon as Braces, CheckIcon as Check, WarningCircleIcon as CircleAlert, CodeIcon as Code, EyeIcon as Eye, GlobeIcon as Globe, ArrowCounterClockwiseIcon as RotateCcw, FloppyDiskIcon as Save } from '@phosphor-icons/react';
9
+ import { WarningIcon as AlertTriangle, BracketsCurlyIcon as Braces, CheckIcon as Check, WarningCircleIcon as CircleAlert, CodeIcon as Code, EyeIcon as Eye, GlobeIcon as Globe, ArrowCounterClockwiseIcon as RotateCcw, FloppyDiskIcon as Save, } from '@phosphor-icons/react';
10
+ import { createPortal } from 'react-dom';
10
11
  import { Download } from '../../internal/icons/download.js';
11
- export function FileHeader({ showHeader, Breadcrumbs, filePath, readOnly, hasUnsavedChanges, saveFlash, fileDiagErrorCount, fileDiagWarningCount, fileContent, isSaving, handleSave, latestContentRef, discardLabel, handleDiscard, isHtmlFile, isHtmlPreview, setIsHtmlPreview, isJsonFile, isJsonTreeView, setIsJsonTreeView, hasPreviewToggle, isMarkdownPreview, setIsMarkdownPreview, headerActions, handleDownload, blobUrl, rawBlob, tI18nHardcoded, tHardcodedUi }) {
12
- return (_jsx(_Fragment, { children: showHeader && (_jsxs("div", { className: "border-border/50 flex h-10 shrink-0 items-center gap-2 border-b px-3 py-1.5", children: [_jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-1", children: [Breadcrumbs && _jsx(Breadcrumbs, { filePath: filePath }), !readOnly && hasUnsavedChanges && (_jsxs(Badge, { variant: "warning", size: "sm", className: "shrink-0", children: [_jsx(StatusDot, { tone: "warning", pulse: true }), tI18nHardcoded.raw('i18nComplete.text7117f0807129')] })), !readOnly && saveFlash && !hasUnsavedChanges && (_jsxs(Badge, { variant: "success", size: "sm", className: "shrink-0", children: [_jsx(Check, { className: "h-3 w-3" }), tI18nHardcoded.raw('i18nComplete.textb5c120b316c2')] })), readOnly && (_jsx(Badge, { variant: "muted", size: "sm", className: "shrink-0 tracking-wider uppercase", children: tHardcodedUi.raw('featuresFilesComponentsFileContentRenderer.line554JsxTextViewOnly') })), (fileDiagErrorCount > 0 || fileDiagWarningCount > 0) && (_jsxs("span", { className: "inline-flex shrink-0 items-center gap-1.5", children: [fileDiagErrorCount > 0 && (_jsxs("span", { className: "text-destructive inline-flex items-center gap-0.5 text-xs font-medium tabular-nums", children: [_jsx(CircleAlert, { className: "h-3 w-3" }), fileDiagErrorCount] })), fileDiagWarningCount > 0 && (_jsxs("span", { className: "text-kortix-orange inline-flex items-center gap-0.5 text-xs font-medium tabular-nums", children: [_jsx(AlertTriangle, { className: "h-3 w-3" }), fileDiagWarningCount] }))] }))] }), _jsxs("div", { className: "flex shrink-0 items-center gap-0.5", children: [!readOnly && hasUnsavedChanges && fileContent?.type === 'text' && (_jsxs(_Fragment, { children: [_jsxs(Button, { variant: "default", size: "sm", className: "h-7 gap-1.5 px-3 text-xs font-medium", onClick: () => { void handleSave(latestContentRef.current).catch(() => undefined); }, disabled: isSaving, title: tHardcodedUi.raw('featuresFilesComponentsFileContentRenderer.line586JsxAttrTitleSaveS'), children: [isSaving ? (_jsx(Loading, { className: "h-3.5 w-3.5" })) : (_jsx(Save, { className: "h-3.5 w-3.5" })), tI18nHardcoded.raw('i18nComplete.text1509f561f241')] }), _jsx(Hint, { label: discardLabel, side: "bottom", children: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": discardLabel, className: "text-muted-foreground hover:text-foreground h-7 w-7 active:scale-[0.96]", onClick: handleDiscard, children: _jsx(RotateCcw, { className: "h-3.5 w-3.5" }) }) })] })), isHtmlFile && (_jsx(Hint, { label: isHtmlPreview ? tI18nHardcoded.raw('i18nComplete.text6ee818aa2de3') : 'Preview', side: "bottom", children: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": isHtmlPreview ? tI18nHardcoded.raw('i18nComplete.text6ee818aa2de3') : 'Preview', "aria-pressed": isHtmlPreview, className: cn('h-7 w-7 active:scale-[0.96]', isHtmlPreview && 'text-primary'), onClick: () => setIsHtmlPreview((v) => !v), children: isHtmlPreview ? _jsx(Code, { className: "h-4 w-4" }) : _jsx(Globe, { className: "h-4 w-4" }) }) })), isJsonFile && fileContent?.type === 'text' && (_jsx(Hint, { label: isJsonTreeView
13
- ? tI18nHardcoded.raw('i18nComplete.text6ee818aa2de3')
14
- : tI18nHardcoded.raw('i18nComplete.text4f50bda41e87'), side: "bottom", children: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": isJsonTreeView
15
- ? tI18nHardcoded.raw('i18nComplete.text6ee818aa2de3')
16
- : tI18nHardcoded.raw('i18nComplete.text4f50bda41e87'), "aria-pressed": isJsonTreeView, className: cn('h-7 w-7 active:scale-[0.96]', isJsonTreeView && 'text-primary'), onClick: () => setIsJsonTreeView((v) => !v), children: _jsx(Braces, { className: "h-4 w-4" }) }) })), hasPreviewToggle && fileContent?.type === 'text' && (_jsx(Hint, { label: isMarkdownPreview
17
- ? tI18nHardcoded.raw('i18nComplete.text6ee818aa2de3')
18
- : 'Preview', side: "bottom", children: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": isMarkdownPreview
19
- ? tI18nHardcoded.raw('i18nComplete.text6ee818aa2de3')
20
- : 'Preview', "aria-pressed": isMarkdownPreview, className: cn('h-7 w-7 active:scale-[0.96]', isMarkdownPreview && 'text-primary'), onClick: () => setIsMarkdownPreview((v) => !v), children: isMarkdownPreview ? _jsx(Code, { className: "h-4 w-4" }) : _jsx(Eye, { className: "h-4 w-4" }) }) })), headerActions, _jsxs(Button, { variant: "outline", size: "sm", className: "h-7 gap-1.5 px-3 text-xs font-medium", onClick: handleDownload, disabled: !fileContent && !blobUrl && !rawBlob, "aria-label": tI18nHardcoded.raw('i18nComplete.textd6eafe823591'), children: [_jsx(Download, { className: "h-3.5 w-3.5" }), tI18nHardcoded.raw('i18nComplete.textd6eafe823591')] })] })] })) }));
12
+ export function FileHeader({ showHeader, headerSlot, Breadcrumbs, filePath, readOnly, hasUnsavedChanges, saveFlash, fileDiagErrorCount, fileDiagWarningCount, fileContent, isSaving, handleSave, latestContentRef, discardLabel, handleDiscard, isHtmlFile, isHtmlPreview, setIsHtmlPreview, isJsonFile, isJsonTreeView, setIsJsonTreeView, hasPreviewToggle, isMarkdownPreview, setIsMarkdownPreview, headerActions, handleDownload, blobUrl, rawBlob, tI18nHardcoded, tHardcodedUi, }) {
13
+ const status = (_jsxs(_Fragment, { children: [!readOnly && hasUnsavedChanges && (_jsxs(Badge, { variant: "warning", size: "sm", className: "shrink-0", children: [_jsx(StatusDot, { tone: "warning", pulse: true }), tI18nHardcoded.raw('i18nComplete.text7117f0807129')] })), !readOnly && saveFlash && !hasUnsavedChanges && (_jsxs(Badge, { variant: "success", size: "sm", className: "shrink-0", children: [_jsx(Check, { className: "h-3 w-3" }), tI18nHardcoded.raw('i18nComplete.textb5c120b316c2')] })), readOnly && (_jsx(Badge, { variant: "muted", size: "sm", className: "shrink-0 tracking-wider uppercase", children: tHardcodedUi.raw('featuresFilesComponentsFileContentRenderer.line554JsxTextViewOnly') })), (fileDiagErrorCount > 0 || fileDiagWarningCount > 0) && (_jsxs("span", { className: "inline-flex shrink-0 items-center gap-1.5", children: [fileDiagErrorCount > 0 && (_jsxs("span", { className: "text-destructive inline-flex items-center gap-0.5 text-xs font-medium tabular-nums", children: [_jsx(CircleAlert, { className: "h-3 w-3" }), fileDiagErrorCount] })), fileDiagWarningCount > 0 && (_jsxs("span", { className: "text-kortix-orange inline-flex items-center gap-0.5 text-xs font-medium tabular-nums", children: [_jsx(AlertTriangle, { className: "h-3 w-3" }), fileDiagWarningCount] }))] }))] }));
14
+ const editActions = (_jsxs(_Fragment, { children: [!readOnly && hasUnsavedChanges && fileContent?.type === 'text' && (_jsxs(_Fragment, { children: [_jsxs(Button, { variant: "default", size: "sm", className: "h-7 gap-1.5 px-3 text-xs font-medium", onClick: () => {
15
+ void handleSave(latestContentRef.current).catch(() => undefined);
16
+ }, disabled: isSaving, title: tHardcodedUi.raw('featuresFilesComponentsFileContentRenderer.line586JsxAttrTitleSaveS'), children: [isSaving ? _jsx(Loading, { className: "h-3.5 w-3.5" }) : _jsx(Save, { className: "h-3.5 w-3.5" }), tI18nHardcoded.raw('i18nComplete.text1509f561f241')] }), _jsx(Hint, { label: discardLabel, side: "bottom", children: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": discardLabel, className: "text-muted-foreground hover:text-foreground h-7 w-7 active:scale-[0.96]", onClick: handleDiscard, children: _jsx(RotateCcw, { className: "h-3.5 w-3.5" }) }) })] })), isHtmlFile && (_jsx(Hint, { label: isHtmlPreview ? tI18nHardcoded.raw('i18nComplete.text6ee818aa2de3') : 'Preview', side: "bottom", children: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": isHtmlPreview ? tI18nHardcoded.raw('i18nComplete.text6ee818aa2de3') : 'Preview', "aria-pressed": isHtmlPreview, className: cn('h-7 w-7 active:scale-[0.96]', isHtmlPreview && 'text-primary'), onClick: () => setIsHtmlPreview((v) => !v), children: isHtmlPreview ? _jsx(Code, { className: "h-4 w-4" }) : _jsx(Globe, { className: "h-4 w-4" }) }) })), isJsonFile && fileContent?.type === 'text' && (_jsx(Hint, { label: isJsonTreeView
17
+ ? tI18nHardcoded.raw('i18nComplete.text6ee818aa2de3')
18
+ : tI18nHardcoded.raw('i18nComplete.text4f50bda41e87'), side: "bottom", children: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": isJsonTreeView
19
+ ? tI18nHardcoded.raw('i18nComplete.text6ee818aa2de3')
20
+ : tI18nHardcoded.raw('i18nComplete.text4f50bda41e87'), "aria-pressed": isJsonTreeView, className: cn('h-7 w-7 active:scale-[0.96]', isJsonTreeView && 'text-primary'), onClick: () => setIsJsonTreeView((v) => !v), children: _jsx(Braces, { className: "h-4 w-4" }) }) }))] }));
21
+ // `null` while the host toolbar mounts: render nothing rather than a row.
22
+ if (headerSlot !== undefined) {
23
+ return showHeader && headerSlot
24
+ ? createPortal(_jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [status, editActions] }), headerSlot)
25
+ : null;
26
+ }
27
+ if (!showHeader)
28
+ return null;
29
+ return (_jsxs("div", { className: "border-border/50 flex h-10 shrink-0 items-center gap-2 border-b px-3 py-1.5", children: [_jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-1", children: [Breadcrumbs && _jsx(Breadcrumbs, { filePath: filePath }), status] }), _jsxs("div", { className: "flex shrink-0 items-center gap-0.5", children: [editActions, hasPreviewToggle && fileContent?.type === 'text' && (_jsx(Hint, { label: isMarkdownPreview ? tI18nHardcoded.raw('i18nComplete.text6ee818aa2de3') : 'Preview', side: "bottom", children: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": isMarkdownPreview ? tI18nHardcoded.raw('i18nComplete.text6ee818aa2de3') : 'Preview', "aria-pressed": isMarkdownPreview, className: cn('h-7 w-7 active:scale-[0.96]', isMarkdownPreview && 'text-primary'), onClick: () => setIsMarkdownPreview((v) => !v), children: isMarkdownPreview ? _jsx(Code, { className: "h-4 w-4" }) : _jsx(Eye, { className: "h-4 w-4" }) }) })), headerActions, _jsxs(Button, { variant: "outline", size: "sm", className: "h-7 gap-1.5 px-3 text-xs font-medium", onClick: handleDownload, disabled: !fileContent && !blobUrl && !rawBlob, "aria-label": tI18nHardcoded.raw('i18nComplete.textd6eafe823591'), children: [_jsx(Download, { className: "h-3.5 w-3.5" }), tI18nHardcoded.raw('i18nComplete.textd6eafe823591')] })] })] }));
21
30
  }
@@ -60,4 +60,4 @@ export interface FilePreviewModalProps extends FilePreviewState {
60
60
  * hit that path, which is why only the mouse appeared broken.)
61
61
  * Z-index is dialog-depth aware so it always stacks above its host overlay.
62
62
  */
63
- export declare function FilePreviewModal({ selectedFilePath, panelMode, filePathList, currentFileIndex, onClose: closePreview, onNext: nextPreview, onPrev: prevPreview, source, HistoryContent, statusSlot, extraActions, shareContext, historyLabel, embedded, targetLine, }: FilePreviewModalProps): import("react").JSX.Element | null;
63
+ export declare function FilePreviewModal({ selectedFilePath, panelMode, filePathList, currentFileIndex, onClose: closePreview, onNext: nextPreview, onPrev: prevPreview, source, HistoryContent, renderFileIcon, statusSlot, extraActions, shareContext, historyLabel, embedded, targetLine, }: FilePreviewModalProps): import("react").JSX.Element | null;
@@ -1,22 +1,21 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { PublicShareLinkButton } from "../../internal/share/public-share-link-button.js";
4
3
  import { Button } from "../../primitives/button.js";
5
4
  import { ButtonGroup } from "../../primitives/button-group.js";
6
5
  import Hint from "../../primitives/hint.js";
7
- import Loading from "../../primitives/loading.js";
8
6
  import { errorToast, successToast } from "../../primitives/toast.js";
9
7
  import { Download } from "../../internal/icons/download.js";
10
8
  import { useTranslations } from "../../i18n/index.js";
11
9
  import { cn } from "../../lib/utils.js";
12
10
  import { dialogContentZ, DialogDepthProvider, dialogOverlayZ, useDialogLayerDepth, } from "../../lib/z-stack.js";
13
- import { ArrowClockwiseIcon, CaretLeftIcon as ChevronLeft, CaretRightIcon as ChevronRight, CodeIcon as Code, EyeIcon as Eye, ClockCounterClockwiseIcon as History, ArrowsOutSimpleIcon as Maximize2, ArrowsInSimpleIcon as Minimize2, XIcon as X, } from "@phosphor-icons/react";
14
- import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, } from "react";
11
+ import { CaretLeftIcon as ChevronLeft, CaretRightIcon as ChevronRight, CodeIcon as Code, EyeIcon as Eye, ClockCounterClockwiseIcon as History, ArrowsOutSimpleIcon as Maximize2, ArrowsInSimpleIcon as Minimize2, XIcon as X, } from "@phosphor-icons/react";
12
+ import { useCallback, useEffect, useLayoutEffect, useRef, useState, } from "react";
15
13
  import { createPortal } from "react-dom";
16
14
  import { FileContentRenderer } from "./file-content-renderer.js";
17
15
  import { FileSourceProvider, } from "./file-source.js";
18
16
  import { getLanguageFromExt } from "./preview-policy.js";
19
17
  import { SaveAsPdfButton } from "./save-as-pdf-button.js";
18
+ import { RefreshButton, ViewerActions, ViewerPathPill, fileShareInput, } from "./viewer-actions.js";
20
19
  /** Tabbable elements used by the focus trap below. */
21
20
  const FOCUSABLE_SELECTOR = [
22
21
  "a[href]",
@@ -54,7 +53,7 @@ const NO_REFRESH = {
54
53
  * hit that path, which is why only the mouse appeared broken.)
55
54
  * Z-index is dialog-depth aware so it always stacks above its host overlay.
56
55
  */
57
- export function FilePreviewModal({ selectedFilePath, panelMode, filePathList, currentFileIndex, onClose: closePreview, onNext: nextPreview, onPrev: prevPreview, source, HistoryContent, statusSlot, extraActions, shareContext, historyLabel = "History", embedded = false, targetLine = null, }) {
56
+ export function FilePreviewModal({ selectedFilePath, panelMode, filePathList, currentFileIndex, onClose: closePreview, onNext: nextPreview, onPrev: prevPreview, source, HistoryContent, renderFileIcon, statusSlot, extraActions, shareContext, historyLabel = "History", embedded = false, targetLine = null, }) {
58
57
  const tI18nHardcoded = useTranslations("hardcodedUi");
59
58
  const isOpen = panelMode === "viewer" && !!selectedFilePath;
60
59
  const [dirty, setDirty] = useState(false);
@@ -81,7 +80,6 @@ export function FilePreviewModal({ selectedFilePath, panelMode, filePathList, cu
81
80
  // renders — the same pattern `FileContentRenderer` uses for `useFileContent`.
82
81
  const useRefresh = source.useRefresh ?? useNoRefresh;
83
82
  const { refresh, refreshing, reloadKey } = useRefresh(selectedFilePath);
84
- const refreshLabel = tI18nHardcoded.raw("i18nComplete.text0e9161011702");
85
83
  const [markdownPreview, setMarkdownPreview] = useState(true);
86
84
  // Markdown and Mermaid files both open rendered, with a Source toggle.
87
85
  const isMarkdownFile = ["markdown", "mermaid"].includes(getLanguageFromExt(fileName));
@@ -90,17 +88,6 @@ export function FilePreviewModal({ selectedFilePath, panelMode, filePathList, cu
90
88
  // The PDF export renders through a session's sandbox; a bytes-only source has none.
91
89
  const exportsPdf = getLanguageFromExt(fileName) === "markdown" && !source.bytesOnly;
92
90
  const { data: pdfSource } = source.useFileContent(exportsPdf ? selectedFilePath : null);
93
- const shareInput = useMemo(() => {
94
- if (!selectedFilePath || !shareContext)
95
- return null;
96
- return {
97
- file: {
98
- label: fileName || selectedFilePath,
99
- path: selectedFilePath,
100
- },
101
- mode: "view",
102
- };
103
- }, [fileName, selectedFilePath, shareContext]);
104
91
  // The dialog surface — focus target for the trap and the focus-on-open below.
105
92
  const surfaceRef = useRef(null);
106
93
  // Reset transient view state when the file changes. A jump to a line shows
@@ -228,6 +215,7 @@ export function FilePreviewModal({ selectedFilePath, panelMode, filePathList, cu
228
215
  const [toolbarEl, toolbarRef] = useState(null);
229
216
  const [nameEl, nameRef] = useState(null);
230
217
  const compactToolbar = useCompactRow(toolbarEl, nameEl);
218
+ const [editSlot, editSlotRef] = useState(null);
231
219
  useEffect(() => {
232
220
  if (!isOpen || !fullscreen)
233
221
  return;
@@ -260,22 +248,22 @@ export function FilePreviewModal({ selectedFilePath, panelMode, filePathList, cu
260
248
  // or display:none would clip or collapse it. React context is preserved.
261
249
  if (typeof document === "undefined")
262
250
  return null;
263
- const toolbar = (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2 pl-1", children: [_jsx("span", { ref: nameRef, className: "max-w-[300px] truncate text-sm font-medium", children: fileName }), !compactToolbar && statusSlot] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [isMarkdownFile && (_jsx(Hint, { label: markdownPreview
251
+ const toolbar = (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [_jsxs(ViewerPathPill, { icon: renderFileIcon(fileName), path: selectedFilePath ?? undefined, fileName: fileName, nameRef: nameRef, children: [source.useRefresh && (_jsx(RefreshButton, { onRefresh: refresh, refreshing: refreshing })), _jsx(ViewerActions, { shareContext: shareContext, shareInput: fileShareInput(selectedFilePath ?? undefined, fileName) })] }), !compactToolbar && statusSlot] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [_jsx("div", { ref: editSlotRef, className: "flex items-center empty:hidden" }), isMarkdownFile && (_jsx(Hint, { label: markdownPreview
264
252
  ? tI18nHardcoded.raw("i18nComplete.text6ee818aa2de3")
265
253
  : "Preview", side: "bottom", children: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": markdownPreview
266
254
  ? tI18nHardcoded.raw("i18nComplete.text6ee818aa2de3")
267
255
  : "Preview", "aria-pressed": markdownPreview, className: cn("h-8 w-8 active:scale-[0.96]", markdownPreview
268
256
  ? "text-muted-foreground hover:text-foreground"
269
- : "text-foreground bg-muted"), onClick: () => setMarkdownPreview((v) => !v), children: markdownPreview ? (_jsx(Code, { className: "h-4 w-4" })) : (_jsx(Eye, { className: "h-4 w-4" })) }) })), source.useRefresh && (_jsx(Hint, { label: refreshLabel, side: "bottom", children: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": refreshLabel, "aria-busy": refreshing, disabled: refreshing, className: "text-muted-foreground hover:text-foreground h-8 w-8 active:scale-[0.96]", onClick: refresh, children: refreshing ? (_jsx(Loading, { className: "text-muted-foreground size-4 motion-reduce:animate-none" })) : (_jsx(ArrowClockwiseIcon, { className: "h-4 w-4" })) }) })), filePathList.length > 1 && !compactToolbar && (
257
+ : "text-foreground bg-muted"), onClick: () => setMarkdownPreview((v) => !v), children: markdownPreview ? (_jsx(Code, { className: "h-4 w-4" })) : (_jsx(Eye, { className: "h-4 w-4" })) }) })), filePathList.length > 1 && !compactToolbar && (
270
258
  // Previous / next live with the other actions; the arrow keys still work.
271
259
  _jsxs(ButtonGroup, { children: [_jsx(Hint, { label: tI18nHardcoded.raw("autoFeaturesFileViewerFilePreviewModalJsxAttrTitlePreviousb7cda316"), side: "bottom", children: _jsx(Button, { variant: "secondary", size: "icon-base", disabled: !hasPrev, "aria-label": tI18nHardcoded.raw("autoFeaturesFileViewerFilePreviewModalJsxAttrAriaLabel03ab3a76"), className: "active:scale-[0.96]", onClick: onPrev, children: _jsx(ChevronLeft, { className: "h-4 w-4" }) }) }), _jsx(Hint, { label: tI18nHardcoded.raw("autoFeaturesFileViewerFilePreviewModalJsxAttrTitleNext96666bd8"), side: "bottom", children: _jsx(Button, { variant: "secondary", size: "icon-base", disabled: !hasNext, "aria-label": tI18nHardcoded.raw("autoFeaturesFileViewerFilePreviewModalJsxAttrAriaLabelda6ea7e4"), className: "active:scale-[0.96]", onClick: onNext, children: _jsx(ChevronRight, { className: "h-4 w-4" }) }) })] })), _jsxs(ButtonGroup, { children: [_jsx(Hint, { label: historyLabel, side: "bottom", children: _jsx(Button, { variant: "secondary", size: "icon-base", "aria-label": historyLabel, "aria-pressed": !!historyPath, className: cn("active:scale-[0.96]", historyPath && "bg-accent"), onClick: () => setHistoryPath(historyPath ? null : selectedFilePath), children: _jsx(History, { className: "h-4 w-4" }) }) }), exportsPdf && !compactToolbar && (_jsx(SaveAsPdfButton, { fileName: fileName, content: pdfSource?.type === "text" ? pdfSource.content : undefined, variant: "secondary", className: "h-8 w-8", iconClassName: "h-4 w-4" })), _jsxs(Button, { variant: "secondary", size: "sm", className: "gap-1.5 active:scale-[0.96]", onClick: handleDownload, "aria-label": tI18nHardcoded.raw("i18nComplete.textd6eafe823591"), children: [_jsx(Download, { className: "h-3.5 w-3.5" }), !compactToolbar &&
272
- tI18nHardcoded.raw("i18nComplete.textd6eafe823591")] })] }), shareContext && !compactToolbar && (_jsx(PublicShareLinkButton, { projectId: shareContext.projectId, sessionId: shareContext.sessionId, input: shareInput, tooltip: tI18nHardcoded.raw("autoFeaturesFileViewerFilePreviewModalJsxAttrTooltipCopy42229181"), className: "text-muted-foreground hover:text-foreground" })), extraActions, embedded && (_jsx(Hint, { label: expanded
260
+ tI18nHardcoded.raw("i18nComplete.textd6eafe823591")] })] }), extraActions, embedded && (_jsx(Hint, { label: expanded
273
261
  ? tI18nHardcoded.raw("i18nComplete.textde12e3c7c7a8")
274
262
  : "Expand", side: "bottom", children: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": expanded
275
263
  ? tI18nHardcoded.raw("i18nComplete.textde12e3c7c7a8")
276
264
  : "Expand", "aria-pressed": expanded, className: "text-muted-foreground hover:text-foreground h-8 w-8 active:scale-[0.96]", onClick: () => setExpanded((v) => !v), children: expanded ? (_jsx(Minimize2, { className: "h-4 w-4" })) : (_jsx(Maximize2, { className: "h-4 w-4" })) }) })), _jsx(ButtonGroup, { className: "ml-1.5", children: _jsx(Hint, { label: tI18nHardcoded.raw("autoFeaturesFileViewerFilePreviewModalJsxAttrTitleClosea40d0510"), side: "bottom", children: _jsx(Button, { variant: "secondary", size: "icon-base", "aria-label": tI18nHardcoded.raw("autoFeaturesFileViewerFilePreviewModalJsxAttrTitleClosea40d0510"), className: "active:scale-[0.96]", onClick: onClose, children: _jsx(X, { className: "h-4 w-4" }) }) }) })] })] }));
277
- const body = (_jsxs(_Fragment, { children: [_jsx("div", { className: "h-full w-full overflow-hidden px-3 pt-3 pb-2", children: _jsx(FileSourceProvider, { value: source, children: _jsx(FileContentRenderer, { filePath: selectedFilePath, reloadKey: reloadKey, onUnsavedChange: setDirty, showHeader: !!source.editablePreview, readOnly: !source.editablePreview, targetLine: targetLine, markdownPreview: markdownPreview, onMarkdownPreviewChange: setMarkdownPreview }) }) }), historyPath && (_jsx("div", { className: "bg-popover border-border/60 animate-in slide-in-from-bottom-4 fade-in-0 absolute right-4 bottom-4 z-30 overflow-hidden rounded-md border shadow-md duration-normal", children: _jsx(HistoryContent, { filePath: historyPath, onClose: () => setHistoryPath(null) }) }))] }));
278
- const panelInner = (_jsxs(_Fragment, { children: [_jsx("div", { ref: toolbarRef, className: "border-border/40 bg-background/95 flex h-12 shrink-0 items-center gap-2 border-b px-3 backdrop-blur-sm", children: toolbar }), _jsx("div", { ref: contentRef, className: "relative min-h-0 flex-1 overflow-hidden", children: body })] }));
265
+ const body = (_jsxs(_Fragment, { children: [_jsx("div", { className: "h-full w-full overflow-hidden px-3 pt-3 pb-2", children: _jsx(FileSourceProvider, { value: source, children: _jsx(FileContentRenderer, { filePath: selectedFilePath, showCaption: true, reloadKey: reloadKey, onUnsavedChange: setDirty, showHeader: !!source.editablePreview, headerSlot: editSlot, readOnly: !source.editablePreview, targetLine: targetLine, markdownPreview: markdownPreview, onMarkdownPreviewChange: setMarkdownPreview }) }) }), historyPath && (_jsx("div", { className: "bg-popover border-border/60 animate-in slide-in-from-bottom-4 fade-in-0 absolute right-4 bottom-4 z-30 overflow-hidden rounded-md border shadow-md duration-normal", children: _jsx(HistoryContent, { filePath: historyPath, onClose: () => setHistoryPath(null) }) }))] }));
266
+ const panelInner = (_jsxs(_Fragment, { children: [_jsx("div", { ref: toolbarRef, "data-file-toolbar": "", className: "border-border/40 bg-background/95 flex h-12 shrink-0 items-center gap-2 border-b px-3 backdrop-blur-sm", children: toolbar }), _jsx("div", { ref: contentRef, className: "relative min-h-0 flex-1 overflow-hidden", children: body })] }));
279
267
  // Inline (embedded, not expanded): fill the relative parent — the side panel —
280
268
  // instead of portaling to a full-screen overlay. No backdrop, no body lock.
281
269
  if (!fullscreen) {
@@ -105,6 +105,19 @@ export interface FileSource {
105
105
  * `reloadKey` goes to `<FileContentRenderer reloadKey>`.
106
106
  */
107
107
  useRefresh?: (filePath: string | null) => FileRefreshResult;
108
+ /**
109
+ * The page's shared image store (R38), for a source whose paths are the live
110
+ * sandbox's: a raster image draws from the bytes another surface (the image
111
+ * card, a `show` card) already loaded, else is read once as bytes. A source
112
+ * with other paths (a git ref, a Drive, a share) omits it.
113
+ */
114
+ useSharedImage?: (filePath: string | null, sha256?: string | null) => SharedImageResult;
115
+ }
116
+ export interface SharedImageResult {
117
+ url: string | null;
118
+ loading: boolean;
119
+ error: string | null;
120
+ retry: () => void;
108
121
  }
109
122
  export interface FileRefreshResult {
110
123
  refresh: () => void;
@@ -43,6 +43,8 @@ export declare function useFileContentState({ filePath, onUnsavedChange, onSaved
43
43
  rawBlob: Blob | null;
44
44
  blobLoading: boolean;
45
45
  blobError: string | null;
46
+ sharedImagePath: string | null;
47
+ retrySharedImage: () => void;
46
48
  heicImageUrl: string | null;
47
49
  heicConverting: boolean;
48
50
  displayContent: string;
@@ -4,9 +4,10 @@ import { errorToast, successToast } from '../../primitives/toast.js';
4
4
  import { useHeicBlob } from '../../internal/hooks/use-heic-url.js';
5
5
  import { isHeicFile } from '../../internal/lib/utils/heic-convert.js';
6
6
  import { findDiagnosticsForFile, useDiagnosticsStore } from '../../internal/stores/diagnostics-store.js';
7
- import { isSandboxNotReadyError } from '@kortix/sdk';
7
+ import { isRuntimeStartingError } from '@kortix/sdk';
8
8
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
9
9
  import { useFileSource } from './file-source.js';
10
+ import { useFileCaption } from '../../internal/stores/file-preview-store.js';
10
11
  import { getFileCategory, getLanguageFromExt } from './preview-policy.js';
11
12
  import { usePreviewFit } from './preview-fit.js';
12
13
  import { useContentRevision } from './use-content-revision.js';
@@ -15,6 +16,10 @@ const BLOB_CATEGORIES = ['docx', 'video', 'audio', 'pptx', 'zip'];
15
16
  function isImageMime(mimeType) {
16
17
  return !!mimeType && mimeType.startsWith('image/');
17
18
  }
19
+ /** The raster images the shared image store holds (R38): not SVG (text), not HEIC (converted). */
20
+ const RASTER_IMAGE = /\.(png|jpe?g|gif|webp|bmp|avif)$/i;
21
+ const NO_SHARED_IMAGE = { url: null, loading: false, error: null, retry: () => { } };
22
+ const noSharedImage = () => NO_SHARED_IMAGE;
18
23
  function isBlobCategory(cat) {
19
24
  return BLOB_CATEGORIES.includes(cat);
20
25
  }
@@ -52,7 +57,15 @@ export function useFileContentState({ filePath, onUnsavedChange, onSaved, readOn
52
57
  // BLOB_CATEGORY). Keyed off the filename alone, so it cannot depend on the
53
58
  // response it is disabling.
54
59
  const isZipArchive = getFileCategory(fileName) === 'zip';
55
- const { data: fileContent, isLoading, error, refetch, dataUpdatedAt, } = useFileContent(isHeicImage || isZipArchive ? null : filePath);
60
+ // A raster image of the live workspace draws from the page's shared image
61
+ // store: the bytes the image card already loaded, at once, else one read of
62
+ // the file as bytes. Never the base64 text read, a second download of the
63
+ // same picture under another cache key (R38).
64
+ const sharedImagePath = source.useSharedImage && RASTER_IMAGE.test(fileName) ? filePath : null;
65
+ // An image the card opened names its bytes' sha256: drawn from the store with no read.
66
+ const sharedImageSha = useFileCaption(filePath)?.sha256;
67
+ const sharedImage = (source.useSharedImage ?? noSharedImage)(sharedImagePath, sharedImageSha);
68
+ const { data: fileContent, isLoading, error, refetch, dataUpdatedAt, } = useFileContent(isHeicImage || isZipArchive || sharedImagePath ? null : filePath);
56
69
  // The agent's turn end refetches this file. The xlsx and sqlite renderers
57
70
  // read their own bytes, so they remount only when the content really
58
71
  // changed (structural sharing keeps the reference otherwise). The HTML frame
@@ -123,7 +136,10 @@ export function useFileContentState({ filePath, onUnsavedChange, onSaved, readOn
123
136
  // there is no sandbox behind Files.
124
137
  const readsOwnBytes = fileCategory === 'xlsx' || fileCategory === 'sqlite';
125
138
  const blobPath = isBlobCategory(fileCategory) || isHeicImage || (source.bytesOnly && readsOwnBytes) ? filePath : null;
126
- const { blobUrl, blob: rawBlob, isLoading: blobLoading, error: blobError, } = useBinaryBlob(blobPath);
139
+ const { blobUrl, blob: rawBlob, isLoading: binaryLoading, error: binaryError, } = useBinaryBlob(blobPath);
140
+ const blobLoading = sharedImagePath ? sharedImage.loading : binaryLoading;
141
+ const blobError = sharedImagePath ? sharedImage.error : binaryError;
142
+ const hasBytes = sharedImagePath ? !!sharedImage.url : !!rawBlob;
127
143
  // HEIC conversion — converts the raw HEIC blob to a renderable JPEG URL
128
144
  const { url: heicImageUrl, isConverting: heicConverting } = useHeicBlob(isHeicImage ? rawBlob : null, fileName);
129
145
  const displayContent = fileContent?.content ?? '';
@@ -266,13 +282,15 @@ export function useFileContentState({ filePath, onUnsavedChange, onSaved, readOn
266
282
  const imageDataUrl = useMemo(() => {
267
283
  if (isHeicImage)
268
284
  return null;
285
+ if (sharedImagePath)
286
+ return sharedImage.url;
269
287
  if (fileContent?.encoding === 'base64' && isImageMime(fileContent.mimeType)) {
270
288
  return `data:${fileContent.mimeType};base64,${fileContent.content}`;
271
289
  }
272
290
  return null;
273
- }, [fileContent, isHeicImage]);
291
+ }, [fileContent, isHeicImage, sharedImagePath, sharedImage.url]);
274
292
  // Determine loading state
275
- const needsBlob = isBlobCategory(fileCategory) || isHeicImage || (!!source.bytesOnly && readsOwnBytes);
293
+ const needsBlob = isBlobCategory(fileCategory) || isHeicImage || (!!source.bytesOnly && readsOwnBytes) || !!sharedImagePath;
276
294
  const isContentReady = needsBlob ? !blobLoading && !blobError : !isLoading && !error;
277
295
  const contentError = needsBlob
278
296
  ? blobError
@@ -286,7 +304,7 @@ export function useFileContentState({ filePath, onUnsavedChange, onSaved, readOn
286
304
  // state, never a failure. The file hooks keep polling while this is true
287
305
  // (SANDBOX_WAKING_REFETCH_INTERVAL_MS), so the content appears on its own
288
306
  // once the box is up.
289
- const isSandboxWaking = !!contentError && isSandboxNotReadyError(contentError);
307
+ const isSandboxWaking = !!contentError && isRuntimeStartingError(contentError);
290
308
  // Detect "file not found" — either via explicit error or empty resolution
291
309
  const isNotFound = useMemo(() => {
292
310
  if (contentError)
@@ -294,7 +312,7 @@ export function useFileContentState({ filePath, onUnsavedChange, onSaved, readOn
294
312
  // Query settled with no data and no error → file likely doesn't exist
295
313
  if (!showLoadingState && !contentError && !needsBlob && !isLoading && !fileContent)
296
314
  return true;
297
- if (!showLoadingState && !contentError && needsBlob && !blobLoading && !blobError && !rawBlob)
315
+ if (!showLoadingState && !contentError && needsBlob && !blobLoading && !blobError && !hasBytes)
298
316
  return true;
299
317
  return false;
300
318
  }, [
@@ -305,7 +323,7 @@ export function useFileContentState({ filePath, onUnsavedChange, onSaved, readOn
305
323
  fileContent,
306
324
  blobLoading,
307
325
  blobError,
308
- rawBlob,
326
+ hasBytes,
309
327
  ]);
310
328
  // Report load status up (used by `show` cards to hide dead references). Only
311
329
  // fires when a caller opts in via `onStatusChange`; the default viewer is
@@ -327,7 +345,7 @@ export function useFileContentState({ filePath, onUnsavedChange, onSaved, readOn
327
345
  // case the surface itself has to speak for.
328
346
  //
329
347
  // A HEIC whose CONVERSION fails is deliberately not one of them:
330
- // `use-heic-url.ts` catches the `heic2any` rejection and falls back to a blob
348
+ // `use-heic-url.ts` catches the HEIC decoder rejection and falls back to a blob
331
349
  // URL over the raw bytes, which a browser with native HEIC support then
332
350
  // renders correctly. So `heicImageUrl` is set, this predicate is false, and
333
351
  // ImageRenderer mounts. Where the browser also cannot decode it, the release
@@ -363,7 +381,7 @@ export function useFileContentState({ filePath, onUnsavedChange, onSaved, readOn
363
381
  isJsonFile, isHtmlFile, isMarkdownPreview, setIsMarkdownPreview, isJsonTreeView,
364
382
  setIsJsonTreeView, isHtmlPreview, setIsHtmlPreview, fileDiagErrorCount, fileDiagWarningCount,
365
383
  fileDiagnostics, tHardcodedUi, tI18nHardcoded, blobUrl, rawBlob,
366
- blobLoading, blobError, heicImageUrl, heicConverting, displayContent,
384
+ blobLoading, blobError, sharedImagePath, retrySharedImage: sharedImage.retry, heicImageUrl, heicConverting, displayContent,
367
385
  handleDownload, handleSave, handleDiscard, handleEditorChange, imageDataUrl,
368
386
  needsBlob, isContentReady, contentError, showLoadingState, isSandboxWaking,
369
387
  isNotFound,
@@ -39,10 +39,12 @@ export declare function pathCrumbs(path: string | undefined): string[];
39
39
  * Folders truncate before the name does — the name is what tells two open
40
40
  * files apart.
41
41
  */
42
- export declare function ViewerPathPill({ icon, path, fileName, children, }: {
42
+ export declare function ViewerPathPill({ icon, path, fileName, nameRef, children, }: {
43
43
  icon: React.ReactNode;
44
44
  path?: string;
45
45
  fileName: string;
46
+ /** The name element, for a host that measures whether it is still readable. */
47
+ nameRef?: React.Ref<HTMLSpanElement>;
46
48
  /** The file's actions — `RefreshButton`, `ViewerActions`. */
47
49
  children?: React.ReactNode;
48
50
  }): import("react").JSX.Element;
@@ -72,9 +72,9 @@ export function pathCrumbs(path) {
72
72
  * Folders truncate before the name does — the name is what tells two open
73
73
  * files apart.
74
74
  */
75
- export function ViewerPathPill({ icon, path, fileName, children, }) {
75
+ export function ViewerPathPill({ icon, path, fileName, nameRef, children, }) {
76
76
  const crumbs = pathCrumbs(path);
77
- return (_jsxs("span", { className: "bg-muted flex h-8 min-w-0 flex-1 items-center gap-1 rounded-md px-1", children: [_jsx("span", { className: "flex h-6 min-w-6 shrink-0 items-center justify-center", children: icon }), _jsxs("span", { className: "flex min-w-0 flex-1 items-center gap-1.5 text-sm", title: path, children: [crumbs.length > 0 && (_jsxs("span", { className: "text-muted-foreground min-w-0 shrink-[3] truncate", children: [crumbs.join(' / '), " /"] })), _jsx("span", { className: "text-foreground min-w-0 truncate font-medium", children: fileName })] }), children && _jsx(ButtonGroup, { className: "shrink-0", children: children })] }));
77
+ return (_jsxs("span", { className: "bg-muted flex h-8 min-w-0 flex-1 items-center gap-1 rounded-md px-1", children: [_jsx("span", { className: "flex h-6 min-w-6 shrink-0 items-center justify-center", children: icon }), _jsxs("span", { className: "flex min-w-0 flex-1 items-center gap-1.5 text-sm", title: path, children: [crumbs.length > 0 && (_jsxs("span", { className: "text-muted-foreground min-w-0 shrink-[3] truncate", children: [crumbs.join(' / '), " /"] })), _jsx("span", { ref: nameRef, className: "text-foreground min-w-0 truncate font-medium", children: fileName })] }), children && _jsx(ButtonGroup, { className: "shrink-0", children: children })] }));
78
78
  }
79
79
  /**
80
80
  * `true` for 2s after `flash()` — the window a copy button shows its check.
@@ -0,0 +1 @@
1
+ export declare function useMediaQuery(query: string): boolean;
@@ -1,2 +1,7 @@
1
1
  export declare const MOBILE_BREAKPOINT = 768;
2
2
  export declare function useIsMobile(): boolean;
3
+ /**
4
+ * Below Tailwind's `sm` (640px): a phone. The composer's attach / agent row
5
+ * moves under the card only here; a 720px desktop window keeps it inside.
6
+ */
7
+ export declare function useIsPhone(): boolean;
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { useMediaQuery } from './use-media-query.js';
2
3
  export const MOBILE_BREAKPOINT = 768;
3
4
  export function useIsMobile() {
4
5
  const [isMobile, setIsMobile] = React.useState(undefined);
@@ -13,3 +14,10 @@ export function useIsMobile() {
13
14
  }, []);
14
15
  return !!isMobile;
15
16
  }
17
+ /**
18
+ * Below Tailwind's `sm` (640px): a phone. The composer's attach / agent row
19
+ * moves under the card only here; a 720px desktop window keeps it inside.
20
+ */
21
+ export function useIsPhone() {
22
+ return useMediaQuery('(max-width: 639px)');
23
+ }