@nextclaw/ui 0.25.4 → 0.26.0

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 (457) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/.vite/manifest.json +1146 -1390
  3. package/dist/assets/{abnfDiagram-VRR7QNED-DX_u5BBX.js → abnfDiagram-VRR7QNED-Bjrmb5-o.js} +1 -1
  4. package/dist/assets/account-panel-C1S3xtUB.js +1 -0
  5. package/dist/assets/{aiden0z-pptx-renderer.es-C-E9e5yB.js → aiden0z-pptx-renderer.es-DO4DCX3e.js} +1 -1
  6. package/dist/assets/api-D9e9cHtW.js +20 -0
  7. package/dist/assets/app-presenter-provider-J9IgTbc9.js +124 -0
  8. package/dist/assets/appearance-settings-page-BljTr6nB.js +1 -0
  9. package/dist/assets/{arc-Cxwa624o.js → arc-g4XaP3S4.js} +1 -1
  10. package/dist/assets/architecture-TIHT7OUA-BWywYH_m.js +1 -0
  11. package/dist/assets/{architectureDiagram-ZJ3FMSHR-D8mCj0H1.js → architectureDiagram-ZJ3FMSHR-CAP7YDux.js} +1 -1
  12. package/dist/assets/{blockDiagram-677ZJIJ3-CbGC1IHl.js → blockDiagram-677ZJIJ3-DhaP0zUG.js} +1 -1
  13. package/dist/assets/{book-open-xqEj1OLE.js → book-open-vxpV2eSM.js} +1 -1
  14. package/dist/assets/{c4Diagram-LMCZKHZV-BQhGC1Vc.js → c4Diagram-LMCZKHZV-DHCQJJkD.js} +1 -1
  15. package/dist/assets/card-D9NYhSdf.js +1 -0
  16. package/dist/assets/channel-1nKIAEXr.js +1 -0
  17. package/dist/assets/channels-list-page-BiHA1zZd.js +8 -0
  18. package/dist/assets/chunk-2Q5K7J3B-CAwv72v4.js +1 -0
  19. package/dist/assets/{chunk-32BRIVSS-B74ZZwYG.js → chunk-32BRIVSS-BcQlxl4v.js} +1 -1
  20. package/dist/assets/{chunk-52WLFC77-BvmxW_f_.js → chunk-52WLFC77-ClPpG-2S.js} +1 -1
  21. package/dist/assets/{chunk-5FCAYU7R-DQvBRnwL.js → chunk-5FCAYU7R-B_qmYOdX.js} +1 -1
  22. package/dist/assets/{chunk-5HE753X5-CDIH0_y3.js → chunk-5HE753X5-DTO-V56q.js} +1 -1
  23. package/dist/assets/{chunk-5JV3BV7I-CcevlKd-.js → chunk-5JV3BV7I-CU1SOaaG.js} +1 -1
  24. package/dist/assets/{chunk-5TONJI2A-_3dxVdnY.js → chunk-5TONJI2A-CzSDkWNa.js} +1 -1
  25. package/dist/assets/{chunk-5VM5RSS4-pGO5vvo-.js → chunk-5VM5RSS4-ChkfqIRE.js} +1 -1
  26. package/dist/assets/{chunk-7BUUIJ7U-DEKF5uAN.js → chunk-7BUUIJ7U-Du3Ozi62.js} +1 -1
  27. package/dist/assets/{chunk-BIQX33UG-CjBFgq2r.js → chunk-BIQX33UG-C-HVafHB.js} +1 -1
  28. package/dist/assets/{chunk-C7G6YPKG-e_K9OGTz.js → chunk-C7G6YPKG-BSjZ86D0.js} +1 -1
  29. package/dist/assets/{chunk-CQNSW5MT-C2IiHyHz.js → chunk-CQNSW5MT-1D1W2lF6.js} +1 -1
  30. package/dist/assets/{chunk-CYSBUYHQ-DCC6KmGp.js → chunk-CYSBUYHQ-ISpyj_lK.js} +1 -1
  31. package/dist/assets/{chunk-EMLP6XTP-BYGgekQ0.js → chunk-EMLP6XTP-Cp8iUBt2.js} +1 -1
  32. package/dist/assets/{chunk-EX3LRPZG-FGcwuVsA.js → chunk-EX3LRPZG-BN5RzF5j.js} +1 -1
  33. package/dist/assets/{chunk-FWX5IMBZ-CV3Ih_Os.js → chunk-FWX5IMBZ-DecJDW4r.js} +2 -2
  34. package/dist/assets/{chunk-HOUHSVGY-CXpq_hfV.js → chunk-HOUHSVGY-BE_XNgGk.js} +1 -1
  35. package/dist/assets/{chunk-ICXQ74PX-CZIpjupq.js → chunk-ICXQ74PX-BFOKMkWV.js} +1 -1
  36. package/dist/assets/{chunk-JG7HCLWE-CdgwBpW7.js → chunk-JG7HCLWE-DL-pl8VB.js} +1 -1
  37. package/dist/assets/{chunk-JWPE2WC7-BPjAZpOQ.js → chunk-JWPE2WC7-B-bcwfmh.js} +1 -1
  38. package/dist/assets/{chunk-MOJQB5TN-DbJDm8to.js → chunk-MOJQB5TN-BC0taFro.js} +1 -1
  39. package/dist/assets/{chunk-MOZMSUNE-BUa1fqKn.js → chunk-MOZMSUNE-RrhfU6MO.js} +1 -1
  40. package/dist/assets/{chunk-OGEWGWER-CtnzLgRu.js → chunk-OGEWGWER-TuI7SR7i.js} +1 -1
  41. package/dist/assets/{chunk-OSBZ3O6U-fUgdpTUM.js → chunk-OSBZ3O6U-C5jMBKlU.js} +1 -1
  42. package/dist/assets/{chunk-PUDLZKDR-CtDWZT9-.js → chunk-PUDLZKDR-C5lMBn0K.js} +1 -1
  43. package/dist/assets/{chunk-Q4XR5HBZ-BxnK2qxr.js → chunk-Q4XR5HBZ-B-kzUbwT.js} +1 -1
  44. package/dist/assets/{chunk-QBLGF6JB-CH4UKoCF.js → chunk-QBLGF6JB-CRb_WAEj.js} +1 -1
  45. package/dist/assets/{chunk-R7FJI6CG-BxwFoF1v.js → chunk-R7FJI6CG-De6Y7ozO.js} +1 -1
  46. package/dist/assets/{chunk-RYQCIY6F-DpHAmq7O.js → chunk-RYQCIY6F-Igv92q8k.js} +1 -1
  47. package/dist/assets/{chunk-U6XO7XAA-BjH2VUHU.js → chunk-U6XO7XAA-bCjRshkT.js} +1 -1
  48. package/dist/assets/{chunk-V7JOEXUC-DKJZ3HGj.js → chunk-V7JOEXUC-0J1s_Kgq.js} +1 -1
  49. package/dist/assets/chunk-VAUOI2AC-DnaryNw2.js +1 -0
  50. package/dist/assets/{chunk-VR4S4FIN-Cf-o2GtI.js → chunk-VR4S4FIN-DX6lXnNx.js} +1 -1
  51. package/dist/assets/{chunk-WYO6CB5R-zeNXGm20.js → chunk-WYO6CB5R-DLqMXfFC.js} +3 -3
  52. package/dist/assets/chunk-XXDRQBXY-BToo1uqb.js +1 -0
  53. package/dist/assets/{chunk-YOTPTUD7-Ck87Kqxe.js → chunk-YOTPTUD7-CY4obsV0.js} +1 -1
  54. package/dist/assets/{chunk-ZGVPDNZ5-BbfK6Bfd.js → chunk-ZGVPDNZ5-BleImZKe.js} +1 -1
  55. package/dist/assets/{chunk-ZIRB5QZD-BDpzh4Yl.js → chunk-ZIRB5QZD-C1TfdjpX.js} +1 -1
  56. package/dist/assets/{circle-dashed-CU3yApvP.js → circle-dashed-CEEssYIw.js} +1 -1
  57. package/dist/assets/classDiagram-OUVF2IWQ-D_TusZGx.js +1 -0
  58. package/dist/assets/classDiagram-v2-EOCWNBFH-B1NFZTmS.js +1 -0
  59. package/dist/assets/client-C6YQx7A-.js +1 -0
  60. package/dist/assets/config-split-page-DKPelvjR.js +1 -0
  61. package/dist/assets/confirm-dialog-BCGeh61X.js +1 -0
  62. package/dist/assets/{cose-bilkent-JH36ORCC-CQfMxKCT.js → cose-bilkent-JH36ORCC-CVgUHXkj.js} +1 -1
  63. package/dist/assets/createLucideIcon-CF8U9dh7.js +1 -0
  64. package/dist/assets/cynefin-VYW2F7L2-CJZSs5s_.js +1 -0
  65. package/dist/assets/{cynefinDiagram-TSTJHNR4-CxFTiC-p.js → cynefinDiagram-TSTJHNR4-cdfImbfI.js} +1 -1
  66. package/dist/assets/{dagre-CaBNMcB1.js → dagre-CHNN9L9I.js} +1 -1
  67. package/dist/assets/{dagre-VKFMJZFB-S_7Hc7bI.js → dagre-VKFMJZFB-PscaENwr.js} +1 -1
  68. package/dist/assets/desktop-capabilities-page-BENHdKfk.js +1 -0
  69. package/dist/assets/desktop-update-config-BJMTQMRS.js +1 -0
  70. package/dist/assets/{diagram-FQU43EPY-C7zENvFb.js → diagram-FQU43EPY-CH_wye41.js} +1 -1
  71. package/dist/assets/{diagram-G47NLZAW-DqYTCqZA.js → diagram-G47NLZAW-Dtjpmi6D.js} +1 -1
  72. package/dist/assets/{diagram-NH7WQ7WH-BfSJtXRc.js → diagram-NH7WQ7WH-UdjLHyaz.js} +1 -1
  73. package/dist/assets/{diagram-OA4YK3LP-CFO-j67H.js → diagram-OA4YK3LP-DYsToEaL.js} +1 -1
  74. package/dist/assets/{diagram-WEI45ONY-DBQDbTaJ.js → diagram-WEI45ONY-CA7kuIer.js} +1 -1
  75. package/dist/assets/dialog-DQXou6pg.js +5 -0
  76. package/dist/assets/dist-CiC9Fd9J.js +1 -0
  77. package/dist/assets/doc-browser-CCYS_csH.js +1 -0
  78. package/dist/assets/doc-browser-context-CPLWVFLd.js +1 -0
  79. package/dist/assets/{docx-preview-B4-aDfvO.js → docx-preview-D--EsUWi.js} +1 -1
  80. package/dist/assets/{ebnfDiagram-CCIWWBDH-CfDNIXFN.js → ebnfDiagram-CCIWWBDH-BrjaoOuq.js} +1 -1
  81. package/dist/assets/{erDiagram-Q63AITRT-D95rFXMM.js → erDiagram-Q63AITRT-nZQa2kCM.js} +1 -1
  82. package/dist/assets/es2015-DHRpDU-q.js +41 -0
  83. package/dist/assets/eventmodeling-45OFAUF4-rc7kUq4V.js +1 -0
  84. package/dist/assets/extensions-CsWT7x3v.js +1 -0
  85. package/dist/assets/{eye-C84inPcV.js → eye-DJtw5KJ5.js} +1 -1
  86. package/dist/assets/flowDiagram-23GEKE2U-DAjaeGO8.js +1 -0
  87. package/dist/assets/form-actions-DDQk0END.js +1 -0
  88. package/dist/assets/{ganttDiagram-NO4QXBWP-Bawg0P0r.js → ganttDiagram-NO4QXBWP-CyFZHIHN.js} +1 -1
  89. package/dist/assets/gitGraph-TEB2WS4Q-Ce0gf6ps.js +1 -0
  90. package/dist/assets/{gitGraphDiagram-IHSO6WYX-BbKh9nbL.js → gitGraphDiagram-IHSO6WYX-Dfpq3z2M.js} +1 -1
  91. package/dist/assets/{i18n-20rSH40D.js → i18n-BjPkAKMQ.js} +2 -2
  92. package/dist/assets/info-DKCQHKI2-Cp-Tr78m.js +1 -0
  93. package/dist/assets/{infoDiagram-FWYZ7A6U-DPffZXYh.js → infoDiagram-FWYZ7A6U-Diiz0k1E.js} +1 -1
  94. package/dist/assets/{ishikawaDiagram-FXEZZL3T-CBMsLwZ2.js → ishikawaDiagram-FXEZZL3T-B3R3SN4M.js} +1 -1
  95. package/dist/assets/{journeyDiagram-5HDEW3XC-Mz5U4OzU.js → journeyDiagram-5HDEW3XC-DFOLKiNv.js} +1 -1
  96. package/dist/assets/{kanban-definition-HUTT4EX6-FXZq2k19.js → kanban-definition-HUTT4EX6-BMXpDp3g.js} +1 -1
  97. package/dist/assets/katex-B4FQSo9k.js +1 -0
  98. package/dist/assets/keyboard-shortcuts-settings-page-hqTP7akj.js +1 -0
  99. package/dist/assets/{line-BZwCgT9K.js → line-64_FhCoJ.js} +1 -1
  100. package/dist/assets/{linear-CTe9mKUw.js → linear-aF1fg7bK.js} +1 -1
  101. package/dist/assets/loader-circle-B-4WwzBj.js +1 -0
  102. package/dist/assets/login-page-BUwshAq4.js +1 -0
  103. package/dist/assets/login-page-CdlI6B8e.js +1 -0
  104. package/dist/assets/main-BVYdyT60.css +1 -0
  105. package/dist/assets/main-DYEALeoQ.js +2 -0
  106. package/dist/assets/main-i18n-catalog.config-1o2hjZ0m.js +1 -0
  107. package/dist/assets/{map-Ci48ZwAp.js → map-BC3Amra3.js} +1 -1
  108. package/dist/assets/mcp-marketplace-page-CRRQT6SP.js +1 -0
  109. package/dist/assets/{mermaid-parser.core-CzPD3U_z.js → mermaid-parser.core-DdMcZwnE.js} +2 -2
  110. package/dist/assets/{mermaid.core-geIMNPbV.js → mermaid.core-BHdiEBbI.js} +3 -3
  111. package/dist/assets/{mindmap-definition-LN4V7U3C-xqlKxsr_.js → mindmap-definition-LN4V7U3C-CtHVaZyV.js} +1 -1
  112. package/dist/assets/model-config-page-BSsHOhV7.js +1 -0
  113. package/dist/assets/navigation-history-CyawyVz0.js +1 -0
  114. package/dist/assets/navigation-link-D-fxdv0i.js +3 -0
  115. package/dist/assets/{ordinal-MxnX8yhv.js → ordinal-6b3jw4cz.js} +1 -1
  116. package/dist/assets/packet-7NZHBO7P-BOJuCraS.js +1 -0
  117. package/dist/assets/panel-app-i18n-catalog.config-kQO7QAwH.js +1 -0
  118. package/dist/assets/panelStandalone-BeI0Ndsx.js +2 -0
  119. package/dist/assets/{pegDiagram-2B236MQR-D50MFTN1.js → pegDiagram-2B236MQR-BtbG3Bgu.js} +1 -1
  120. package/dist/assets/pie-RZYD4A2V-D-FEO81x.js +1 -0
  121. package/dist/assets/{pieDiagram-ENE6RG2P-CpA13oiC.js → pieDiagram-ENE6RG2P-FmLl2hzN.js} +1 -1
  122. package/dist/assets/privacy-settings-page-pW_1naDz.js +1 -0
  123. package/dist/assets/projects-k6SLda_A.js +1 -0
  124. package/dist/assets/provider-models-mVzuEQBS.js +1 -0
  125. package/dist/assets/provider-scoped-model-input-CVbtT8L9.js +1 -0
  126. package/dist/assets/providers-config-page-rBlVrHkb.js +1 -0
  127. package/dist/assets/{puzzle-D6gulz7u.js → puzzle-kKiVft9-.js} +1 -1
  128. package/dist/assets/pwa-BgGM4kkY.js +1 -0
  129. package/dist/assets/{quadrantDiagram-ABIIQ3AL-CYCgaj4l.js → quadrantDiagram-ABIIQ3AL-7-OzMNpF.js} +1 -1
  130. package/dist/assets/radar-I7S5WNFK-Bq3eK1vK.js +1 -0
  131. package/dist/assets/railroad-3IZDKUUU-C3uZ1esg.js +1 -0
  132. package/dist/assets/railroad-abnf-AHOZXSZD-D3iZd1KT.js +1 -0
  133. package/dist/assets/railroad-ebnf-EBAXGLYW-Dl0FWqZu.js +1 -0
  134. package/dist/assets/railroad-peg-LSFZ7HO6-B51SbzGp.js +1 -0
  135. package/dist/assets/{railroadDiagram-RFXS5EU6-4LKDGlXN.js → railroadDiagram-RFXS5EU6-B_UVtLJO.js} +1 -1
  136. package/dist/assets/{refresh-cw-h9Xq3LY3.js → refresh-cw-BeG0y6yZ.js} +1 -1
  137. package/dist/assets/remote-wYWqir2w.js +1 -0
  138. package/dist/assets/{requirementDiagram-TGXJPOKE-CxNOU0JH.js → requirementDiagram-TGXJPOKE-D8TO2YeZ.js} +1 -1
  139. package/dist/assets/{rotate-cw-B6xm41Wn.js → rotate-cw-Ci2dcTO5.js} +1 -1
  140. package/dist/assets/runtime-config-page-DCXN0nkS.js +1 -0
  141. package/dist/assets/{sankeyDiagram-HTMAVEWB-DbCBDe2S.js → sankeyDiagram-HTMAVEWB-CUzIcq0B.js} +1 -1
  142. package/dist/assets/{save-fff_WpY2.js → save-Cr895abt.js} +1 -1
  143. package/dist/assets/search-config-page-CNQd481d.js +1 -0
  144. package/dist/assets/secrets-config-page--q7M58L8.js +3 -0
  145. package/dist/assets/security-config-CJb2pK2O.js +1 -0
  146. package/dist/assets/select-Bq-UmfCK.js +1 -0
  147. package/dist/assets/{sequenceDiagram-DBY2YBRQ-DA6W2BS_.js → sequenceDiagram-DBY2YBRQ-kqJzXbwu.js} +1 -1
  148. package/dist/assets/service-apps-panel-iLLEByRF.js +1 -0
  149. package/dist/assets/{settings-2-CE3ELQyk.js → settings-2-IodCcaXd.js} +1 -1
  150. package/dist/assets/{sizeCapture-X5ZJPWSS-T_q_d_VW.js → sizeCapture-X5ZJPWSS-D9ISogq1.js} +1 -1
  151. package/dist/assets/{src-CYpUlx-4.js → src-Bc0PoUJ1.js} +1 -1
  152. package/dist/assets/{stateDiagram-2N3HPSRC-mi8z2G0a.js → stateDiagram-2N3HPSRC-CqH5xc9W.js} +1 -1
  153. package/dist/assets/stateDiagram-v2-6OUMAXLB-CcOGfDdx.js +1 -0
  154. package/dist/assets/status-dot-DUYSKRCU.js +1 -0
  155. package/dist/assets/{swimlanes-5IMT3BWC-DkBEhWE4.js → swimlanes-5IMT3BWC-mwejV-rW.js} +2 -2
  156. package/dist/assets/swimlanesDiagram-G3AALYLV-BMI2k8RZ.js +8 -0
  157. package/dist/assets/tag-chip-CQU51ST3.js +1 -0
  158. package/dist/assets/theme-provider-D-zZkXxS.js +1 -0
  159. package/dist/assets/{timeline-definition-FHXFAJF6-BoFmqBw1.js → timeline-definition-FHXFAJF6-CuikIDlX.js} +1 -1
  160. package/dist/assets/trash-2-BDdqDh6E.js +1 -0
  161. package/dist/assets/treeView-QDETBFTQ-C0_07QI1.js +1 -0
  162. package/dist/assets/treemap-6X3UGDF4-Djpx6ccG.js +1 -0
  163. package/dist/assets/use-config-Bxx7DdaL.js +1 -0
  164. package/dist/assets/{use-desktop-capabilities-BkuRd2cY.js → use-desktop-capabilities-BTgdFgJy.js} +1 -1
  165. package/dist/assets/use-viewport-layout-CDcca0YL.js +1 -0
  166. package/dist/assets/{vennDiagram-L72KCM5P-BlZ3Or5U.js → vennDiagram-L72KCM5P-BD0P0qHh.js} +1 -1
  167. package/dist/assets/wardley-OPB4EBWU-DZVFxu81.js +1 -0
  168. package/dist/assets/{wardleyDiagram-EHGQE667-yDfr33i3.js → wardleyDiagram-EHGQE667-C6ma3t5D.js} +1 -1
  169. package/dist/assets/x-LUUwl8rK.js +1 -0
  170. package/dist/assets/{xychartDiagram-FW5EYKEG-mIXwIGAQ.js → xychartDiagram-FW5EYKEG-D7E40NBk.js} +1 -1
  171. package/dist/index.html +37 -54
  172. package/dist/panel-standalone.html +11 -15
  173. package/package.json +5 -5
  174. package/src/app/components/layout/__tests__/app-layout.test.tsx +8 -0
  175. package/src/app/components/layout/app-layout.tsx +18 -46
  176. package/src/app/configs/__tests__/app-navigation.config.test.ts +4 -0
  177. package/src/app/configs/app-navigation.config.ts +2 -0
  178. package/src/app/configs/page-resource-renderers.config.ts +13 -0
  179. package/src/app/index.tsx +4 -0
  180. package/src/app/presenters/app.presenter.ts +13 -2
  181. package/src/features/agents/components/__tests__/agents-page.test.tsx +4 -0
  182. package/src/features/agents/components/agent-details-dialog.tsx +3 -0
  183. package/src/features/agents/components/agents-page.tsx +7 -3
  184. package/src/features/apps/components/app-package-card.tsx +2 -2
  185. package/src/features/chat/components/conversation/chat-conversation-content.tsx +32 -19
  186. package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +1 -0
  187. package/src/features/chat/components/conversation/chat-conversation-header.tsx +1 -1
  188. package/src/features/chat/components/conversation/chat-conversation-panel.tsx +2 -2
  189. package/src/features/chat/components/conversation/chat-conversation-workspace-section.tsx +1 -0
  190. package/src/features/chat/components/layout/__tests__/chat-page-shell.test.tsx +7 -6
  191. package/src/features/chat/components/layout/__tests__/chat-sidebar-toolbar.test.tsx +14 -12
  192. package/src/features/chat/components/layout/chat-page-shell.tsx +33 -64
  193. package/src/features/chat/components/layout/chat-sidebar-desktop-layout.tsx +8 -4
  194. package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +64 -256
  195. package/src/features/chat/components/layout/chat-sidebar.tsx +8 -30
  196. package/src/features/chat/components/providers/chat-runtime.provider.tsx +62 -0
  197. package/src/features/chat/features/conversation/components/__tests__/floating-session-conversation.test.tsx +70 -0
  198. package/src/features/chat/features/conversation/components/floating-session-conversation.tsx +27 -0
  199. package/src/features/chat/features/conversation/components/session-conversation-area.tsx +1 -0
  200. package/src/features/chat/features/conversation/components/session-conversation-panel-tab.tsx +25 -0
  201. package/src/features/chat/features/conversation/hooks/use-chat-composer-reference-intent.ts +2 -1
  202. package/src/features/chat/features/message/components/__tests__/chat-inline-panel-app-card.test.tsx +2 -1
  203. package/src/features/chat/features/message/components/__tests__/chat-message-assistant-header.container.test.tsx +3 -0
  204. package/src/features/chat/features/message/components/__tests__/chat-message-list-skill-preview.container.test.tsx +3 -0
  205. package/src/features/chat/features/message/components/__tests__/chat-message-list.container.test.tsx +3 -0
  206. package/src/features/chat/features/message/hooks/use-chat-inline-token-actions.ts +7 -3
  207. package/src/features/chat/features/session/components/__tests__/chat-sidebar-session-item.test.tsx +20 -0
  208. package/src/features/chat/features/session/components/chat-mobile-session-row.tsx +61 -0
  209. package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +0 -35
  210. package/src/features/chat/features/session/components/chat-sidebar-session-entry.tsx +2 -0
  211. package/src/features/chat/features/session/components/chat-sidebar-session-item.tsx +13 -5
  212. package/src/features/chat/features/session/components/chat-sidebar-session-list.tsx +5 -3
  213. package/src/features/chat/features/session/components/session-header/__tests__/chat-session-header-actions.test.tsx +8 -0
  214. package/src/features/chat/features/session/components/session-header/chat-session-header-actions.tsx +3 -0
  215. package/src/features/chat/features/session/components/session-header/chat-session-more-actions-menu.tsx +6 -0
  216. package/src/features/chat/features/session/utils/chat-session-route.utils.ts +12 -0
  217. package/src/features/chat/features/workspace/components/__tests__/chat-session-child-sessions.test.tsx +28 -0
  218. package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-file-preview.test.tsx +9 -0
  219. package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel-content.test.tsx +6 -2
  220. package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel.test.tsx +49 -12
  221. package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx +13 -6
  222. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +6 -0
  223. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-nav.tsx +21 -36
  224. package/src/features/chat/features/workspace/components/chat-session-workspace-panel.tsx +40 -31
  225. package/src/features/chat/features/workspace/components/child-sessions/chat-session-child-sessions.tsx +6 -1
  226. package/src/features/chat/features/workspace/components/project-files/workspace-directory-tree.tsx +2 -2
  227. package/src/features/chat/features/workspace/components/project-files/workspace-project-files-toolbar.tsx +2 -2
  228. package/src/features/chat/features/workspace/utils/__tests__/chat-workspace-panel-view-model.utils.test.ts +27 -0
  229. package/src/features/chat/features/workspace/utils/__tests__/workspace-file-panel-route.utils.test.ts +94 -0
  230. package/src/features/chat/features/workspace/utils/chat-workspace-file-tab-persistence.utils.ts +2 -0
  231. package/src/features/chat/features/workspace/utils/chat-workspace-file-tab.utils.ts +15 -0
  232. package/src/features/chat/features/workspace/utils/chat-workspace-panel-view-model.utils.ts +11 -0
  233. package/src/features/chat/features/workspace/utils/workspace-file-panel-route.utils.ts +147 -0
  234. package/src/features/chat/index.ts +20 -4
  235. package/src/features/chat/managers/__tests__/chat-completion-notification.manager.test.ts +8 -0
  236. package/src/features/chat/managers/__tests__/chat-thread-workspace.manager.test.ts +7 -2
  237. package/src/features/chat/managers/__tests__/session-surface.manager.test.ts +45 -0
  238. package/src/features/chat/managers/chat-completion-notification.manager.ts +5 -0
  239. package/src/features/chat/managers/chat-composer-intent.manager.ts +16 -0
  240. package/src/features/chat/managers/chat-thread.manager.ts +18 -27
  241. package/src/features/chat/managers/session-surface.manager.ts +46 -0
  242. package/src/features/chat/pages/__tests__/ncp-chat-page.test.tsx +23 -5
  243. package/src/features/chat/pages/ncp-chat-page.tsx +6 -86
  244. package/src/features/chat/presenters/chat.presenter.ts +2 -1
  245. package/src/features/chat/stores/__tests__/chat-thread.store.test.ts +2 -2
  246. package/src/features/chat/stores/chat-thread.store.ts +7 -1
  247. package/src/features/chat/stores/floating-session.store.ts +11 -0
  248. package/src/features/cron/components/__tests__/cron-config.test.tsx +4 -0
  249. package/src/features/cron/components/cron-job-detail-dialog.tsx +3 -1
  250. package/src/features/cron/components/cron-job-row.tsx +5 -1
  251. package/src/features/inbox/components/inbox-reader-dialog.test.tsx +3 -0
  252. package/src/features/inbox/components/inbox-reader-dialog.tsx +3 -0
  253. package/src/features/inbox/pages/inbox-page.test.ts +3 -0
  254. package/src/features/inbox/pages/inbox-page.tsx +3 -0
  255. package/src/features/marketplace/components/__tests__/marketplace-page-detail.test.tsx +5 -1
  256. package/src/features/marketplace/components/__tests__/marketplace-page.test.tsx +3 -0
  257. package/src/features/marketplace/components/curated-shelves/__tests__/marketplace-curated-scene-route.test.tsx +2 -0
  258. package/src/features/marketplace/components/marketplace-list-card.tsx +4 -0
  259. package/src/features/marketplace/components/mcp/__tests__/mcp-marketplace-page.test.tsx +2 -0
  260. package/src/features/marketplace/components/mcp/mcp-marketplace-card.tsx +3 -0
  261. package/src/features/notifications/components/__tests__/app-notification-toast.test.tsx +19 -0
  262. package/src/features/notifications/components/app-notification-toast.tsx +33 -15
  263. package/src/features/notifications/managers/app-notification.manager.ts +2 -0
  264. package/src/features/panel-apps/components/__tests__/panel-app-list-item.test.tsx +11 -4
  265. package/src/features/panel-apps/components/__tests__/panel-app-toolbar.test.tsx +11 -5
  266. package/src/features/panel-apps/components/panel-app-main-sidebar-menu-item.tsx +5 -38
  267. package/src/features/panel-apps/index.ts +1 -1
  268. package/src/features/projects/components/project-materials.test.tsx +2 -0
  269. package/src/features/projects/components/project-skills.tsx +7 -3
  270. package/src/features/projects/components/work/project-work-item-drawer.test.tsx +2 -0
  271. package/src/features/projects/components/work/project-work-item-drawer.tsx +3 -1
  272. package/src/features/right-panel-resources/components/__tests__/page-resource-icon.test.tsx +67 -0
  273. package/src/features/right-panel-resources/components/__tests__/page-resource-sidebar-nav.test.tsx +158 -0
  274. package/src/features/right-panel-resources/components/__tests__/system-object-resource.test.tsx +42 -0
  275. package/src/features/right-panel-resources/components/current-page-actions.tsx +36 -0
  276. package/src/features/right-panel-resources/components/page-resource-actions-menu.tsx +71 -0
  277. package/src/features/right-panel-resources/components/page-resource-icon.tsx +245 -0
  278. package/src/features/right-panel-resources/components/page-resource-sidebar-nav.tsx +122 -0
  279. package/src/features/right-panel-resources/components/system-object-resource.tsx +100 -0
  280. package/src/features/right-panel-resources/components/workspace-file-resource.tsx +56 -0
  281. package/src/features/right-panel-resources/configs/right-panel-resource-routes.config.ts +46 -3
  282. package/src/features/right-panel-resources/hooks/use-page-resource-actions.ts +137 -0
  283. package/src/features/right-panel-resources/index.ts +22 -8
  284. package/src/features/right-panel-resources/managers/__tests__/page-resource.manager.test.ts +149 -0
  285. package/src/features/right-panel-resources/managers/page-resource.manager.ts +342 -0
  286. package/src/features/right-panel-resources/pages/resource-page.tsx +114 -0
  287. package/src/features/right-panel-resources/stores/page-navigation.store.ts +55 -0
  288. package/src/features/right-panel-resources/types/page-resource.types.ts +11 -0
  289. package/src/features/right-panel-resources/utils/__tests__/right-panel-resource-route-resolver.utils.test.ts +10 -0
  290. package/src/features/right-panel-resources/utils/page-resource-identity.utils.ts +61 -0
  291. package/src/features/right-panel-resources/utils/right-panel-resource-uri.utils.ts +2 -6
  292. package/src/features/service-apps/components/__tests__/service-apps-panel.test.tsx +2 -0
  293. package/src/features/service-apps/components/service-app-list-item.tsx +5 -1
  294. package/src/features/settings/pages/providers-config-page.tsx +2 -2
  295. package/src/features/side-dock/components/__tests__/side-dock.test.tsx +9 -8
  296. package/src/features/side-dock/components/side-dock.tsx +14 -47
  297. package/src/features/side-dock/managers/side-dock.manager.ts +2 -0
  298. package/src/platforms/desktop/components/__tests__/desktop-app-shell.test.tsx +3 -0
  299. package/src/platforms/desktop/components/desktop-app-shell.tsx +5 -14
  300. package/src/platforms/mobile/components/__tests__/mobile-app-shell.test.tsx +1 -0
  301. package/src/platforms/mobile/components/__tests__/mobile-bottom-nav.test.tsx +3 -2
  302. package/src/platforms/mobile/components/mobile-app-shell.tsx +5 -4
  303. package/src/platforms/mobile/components/mobile-bottom-nav.tsx +7 -7
  304. package/src/platforms/mobile/components/mobile-topbar.tsx +4 -4
  305. package/src/shared/components/doc-browser/__tests__/doc-browser-context.test.tsx +4 -3
  306. package/src/shared/components/doc-browser/__tests__/doc-browser-tab-strip.test.tsx +0 -5
  307. package/src/shared/components/doc-browser/__tests__/doc-browser.test.tsx +57 -73
  308. package/src/shared/components/doc-browser/__tests__/resource-link-interceptor.test.tsx +104 -0
  309. package/src/shared/components/doc-browser/doc-browser-context.tsx +5 -1
  310. package/src/shared/components/doc-browser/doc-browser-panel-parts.tsx +1 -1
  311. package/src/shared/components/doc-browser/doc-browser-tab-strip.tsx +6 -118
  312. package/src/shared/components/doc-browser/doc-browser.tsx +30 -194
  313. package/src/shared/components/doc-browser/hooks/use-doc-browser-scroll-restoration.ts +1 -1
  314. package/src/shared/components/doc-browser/managers/doc-browser.manager.ts +11 -1
  315. package/src/shared/components/doc-browser/stores/doc-browser.store.ts +3 -7
  316. package/src/shared/components/doc-browser/types/doc-browser.types.ts +8 -1
  317. package/src/shared/components/doc-browser/use-doc-link-interceptor.ts +30 -32
  318. package/src/shared/components/doc-browser/utils/doc-browser-state.utils.ts +6 -6
  319. package/src/shared/components/ui/context-menu/__tests__/context-menu.test.tsx +22 -0
  320. package/src/shared/components/ui/context-menu/context-menu.tsx +18 -10
  321. package/src/shared/components/workbench/__tests__/workbench-surface.manager.test.ts +70 -0
  322. package/src/shared/components/workbench/__tests__/workbench-surface.test.tsx +111 -0
  323. package/src/shared/components/workbench/managers/workbench-surface.manager.ts +120 -0
  324. package/src/shared/components/workbench/stores/workbench-surface.store.ts +83 -0
  325. package/src/shared/components/workbench/types/workbench-surface.types.ts +32 -0
  326. package/src/shared/components/workbench/utils/workbench-surface-geometry.utils.ts +46 -0
  327. package/src/shared/components/workbench/workbench-surface-toolbar.tsx +102 -0
  328. package/src/shared/components/workbench/workbench-surface.tsx +401 -0
  329. package/src/shared/hooks/use-panel-app-scroll-restoration.test.tsx +19 -0
  330. package/src/shared/hooks/use-panel-app-scroll-restoration.ts +8 -6
  331. package/src/shared/hooks/use-scroll-restoration.test.tsx +39 -2
  332. package/src/shared/hooks/use-scroll-restoration.ts +33 -33
  333. package/src/shared/lib/api/marketplace.types.ts +1 -0
  334. package/src/shared/lib/i18n/locales/en-US/chat.json +38 -0
  335. package/src/shared/lib/i18n/locales/en-US/doc-browser.json +1 -1
  336. package/src/shared/lib/i18n/locales/zh-CN/chat.json +38 -0
  337. package/src/shared/lib/navigation-history/index.ts +1 -0
  338. package/src/shared/lib/navigation-history/navigation-history.utils.ts +1 -1
  339. package/src/shared/lib/navigation-history/scroll-restoration.manager.test.ts +11 -0
  340. package/src/shared/lib/navigation-history/scroll-restoration.manager.ts +36 -7
  341. package/src/shared/lib/navigation-history/view-memory-storage.store.test.ts +37 -0
  342. package/src/shared/lib/navigation-history/view-memory-storage.store.ts +21 -0
  343. package/src/shared/lib/ui-document-title/index.ts +1 -0
  344. package/dist/assets/account-panel-BW4GbzQd.js +0 -1
  345. package/dist/assets/api-DqzQ-_3w.js +0 -13
  346. package/dist/assets/app-data-C54N2p8b.js +0 -1
  347. package/dist/assets/app-presenter-provider-CBZ_-ewx.js +0 -115
  348. package/dist/assets/appearance-settings-page-C-uZ2Wkf.js +0 -1
  349. package/dist/assets/architecture-TIHT7OUA-DEt0Abz9.js +0 -1
  350. package/dist/assets/boxes-D6uPnkGo.js +0 -1
  351. package/dist/assets/card-BhfAZv5L.js +0 -1
  352. package/dist/assets/channel-CxQkbwRD.js +0 -1
  353. package/dist/assets/channels-list-page-Bv7CVSqV.js +0 -8
  354. package/dist/assets/chevron-down-BL-yMYcX.js +0 -1
  355. package/dist/assets/chunk-2Q5K7J3B-ClVhziok.js +0 -1
  356. package/dist/assets/chunk-VAUOI2AC-DZQxkIsv.js +0 -1
  357. package/dist/assets/chunk-XXDRQBXY-BkExtw5C.js +0 -1
  358. package/dist/assets/circle-alert-lSa3LRvS.js +0 -1
  359. package/dist/assets/classDiagram-OUVF2IWQ-Bd6apBb-.js +0 -1
  360. package/dist/assets/classDiagram-v2-EOCWNBFH-CYxUZGCI.js +0 -1
  361. package/dist/assets/client-BtGBwLTs.js +0 -1
  362. package/dist/assets/config-split-page-DqAXKLmG.js +0 -1
  363. package/dist/assets/confirm-dialog-BTKCWMn6.js +0 -1
  364. package/dist/assets/createLucideIcon-BNKf0_kc.js +0 -1
  365. package/dist/assets/cynefin-VYW2F7L2-CV0bFLH9.js +0 -1
  366. package/dist/assets/desktop-capabilities-page-zLzCSB7A.js +0 -1
  367. package/dist/assets/desktop-update-config-PmofcFf6.js +0 -1
  368. package/dist/assets/dialog-Xe73hpQz.js +0 -5
  369. package/dist/assets/dist-BiIcnf9j.js +0 -1
  370. package/dist/assets/dist-C5I0v8Qn.js +0 -1
  371. package/dist/assets/dist-czPa8xFO.js +0 -1
  372. package/dist/assets/doc-browser-BJrre2S_.js +0 -1
  373. package/dist/assets/doc-browser-BPqA-zQx.js +0 -1
  374. package/dist/assets/doc-browser-context-TILuCY5c.js +0 -1
  375. package/dist/assets/ellipsis-C5YXdOUx.js +0 -1
  376. package/dist/assets/es2015-cuwbYI-l.js +0 -41
  377. package/dist/assets/eventmodeling-45OFAUF4-BzkLWWdP.js +0 -1
  378. package/dist/assets/extensions-CVUFK6Jj.js +0 -1
  379. package/dist/assets/flowDiagram-23GEKE2U-ukkCsB0j.js +0 -1
  380. package/dist/assets/form-actions-BRESe-m_.js +0 -1
  381. package/dist/assets/gitGraph-TEB2WS4Q-BYFhT0Q5.js +0 -1
  382. package/dist/assets/i18n-provider-BPRq6S7O.js +0 -1
  383. package/dist/assets/info-DKCQHKI2-CTmlJdcH.js +0 -1
  384. package/dist/assets/katex-DbZC06Q5.js +0 -1
  385. package/dist/assets/keyboard-shortcuts-settings-page-CScSXYS4.js +0 -1
  386. package/dist/assets/loader-circle-K1BDdHR5.js +0 -1
  387. package/dist/assets/login-page-Dlyvp-81.js +0 -1
  388. package/dist/assets/login-page-f8qQ4xKY.js +0 -1
  389. package/dist/assets/logo-badge-C-5-zim6.js +0 -1
  390. package/dist/assets/main-D2dWy8fM.css +0 -1
  391. package/dist/assets/main-DMNmwcJE.js +0 -2
  392. package/dist/assets/main-i18n-catalog.config-DZ-5ollN.js +0 -1
  393. package/dist/assets/mcp-marketplace-page-FfIfEo6w.js +0 -10
  394. package/dist/assets/mcp-marketplace-page-sH7VptN_.js +0 -1
  395. package/dist/assets/model-config-page-Bcm6-pCX.js +0 -1
  396. package/dist/assets/navigation-link-BAQjgx2F.js +0 -3
  397. package/dist/assets/packet-7NZHBO7P-BbrI0ZlN.js +0 -1
  398. package/dist/assets/panel-app-i18n-catalog.config-p3qAY_Eq.js +0 -1
  399. package/dist/assets/panelStandalone-By-6dDXS.js +0 -2
  400. package/dist/assets/pie-RZYD4A2V-B7zE1ZIr.js +0 -1
  401. package/dist/assets/plus-LA8-jpxP.js +0 -1
  402. package/dist/assets/popover-NkrFlWHp.js +0 -1
  403. package/dist/assets/privacy-settings-page-B1sHLAc1.js +0 -1
  404. package/dist/assets/projects-Voql-cvx.js +0 -1
  405. package/dist/assets/provider-models-hrHMcHqg.js +0 -1
  406. package/dist/assets/provider-scoped-model-input-BQsugx1v.js +0 -1
  407. package/dist/assets/providers-config-page-BDEdHJbw.js +0 -1
  408. package/dist/assets/pwa-CzqfYjFx.js +0 -1
  409. package/dist/assets/radar-I7S5WNFK-1X_q11Ed.js +0 -1
  410. package/dist/assets/railroad-3IZDKUUU-CIXnuFyE.js +0 -1
  411. package/dist/assets/railroad-abnf-AHOZXSZD-D6ImKl2r.js +0 -1
  412. package/dist/assets/railroad-ebnf-EBAXGLYW-2j9d3twU.js +0 -1
  413. package/dist/assets/railroad-peg-LSFZ7HO6-DMVaJGbm.js +0 -1
  414. package/dist/assets/remote-BekqL5nA.js +0 -1
  415. package/dist/assets/runtime-config-page-BH9uF4u_.js +0 -1
  416. package/dist/assets/search-CUe41wjm.js +0 -1
  417. package/dist/assets/search-config-page-DWKlMHgH.js +0 -1
  418. package/dist/assets/secrets-config-page-DiQL088Y.js +0 -3
  419. package/dist/assets/security-config-DmTDKKY4.js +0 -1
  420. package/dist/assets/select-CG5YWnwe.js +0 -1
  421. package/dist/assets/service-apps-panel-CEnyYsQp.js +0 -1
  422. package/dist/assets/skeleton-Drvn83YW.js +0 -1
  423. package/dist/assets/stateDiagram-v2-6OUMAXLB-OlIMT57r.js +0 -1
  424. package/dist/assets/swimlanesDiagram-G3AALYLV-sLThrh07.js +0 -8
  425. package/dist/assets/tabs-BuE0qKMh.js +0 -1
  426. package/dist/assets/tag-chip-B1AYPOKL.js +0 -1
  427. package/dist/assets/theme-provider-DzvAi3pe.js +0 -1
  428. package/dist/assets/tooltip-DYcuWhuP.js +0 -1
  429. package/dist/assets/trash-2-BPPYt2NV.js +0 -1
  430. package/dist/assets/treeView-QDETBFTQ-CCFyazDE.js +0 -1
  431. package/dist/assets/treemap-6X3UGDF4-D6wvq1Hz.js +0 -1
  432. package/dist/assets/use-config-BEdbtpD4.js +0 -1
  433. package/dist/assets/use-panel-app-scroll-restoration-ZnicIfo3.js +0 -1
  434. package/dist/assets/use-viewport-layout-BS18drMT.js +0 -1
  435. package/dist/assets/utils-CBZPzC_b.js +0 -8
  436. package/dist/assets/wardley-OPB4EBWU-BRzaRyFf.js +0 -1
  437. package/dist/assets/x-DdXOqLnX.js +0 -1
  438. package/src/features/panel-apps/components/__tests__/panel-app-main-sidebar-nav.test.tsx +0 -219
  439. package/src/features/panel-apps/components/panel-app-main-sidebar-nav.tsx +0 -258
  440. package/src/shared/components/doc-browser/utils/doc-browser-floating-panel.utils.ts +0 -83
  441. /package/dist/assets/{array-D0DyKZdT.js → array-B0sEvCP9.js} +0 -0
  442. /package/dist/assets/{chunk-KEIR6QF5-CuZFOa6q.js → chunk-KEIR6QF5-BeO7fxDQ.js} +0 -0
  443. /package/dist/assets/{chunk-Y2CYZVJY-Frut-1TF.js → chunk-Y2CYZVJY-JQfgEV36.js} +0 -0
  444. /package/dist/assets/{config-hints-B_C9DAp5.js → config-hints-D3OuwoEY.js} +0 -0
  445. /package/dist/assets/{cytoscape.esm-BibuhnZD.js → cytoscape.esm-CzJ9uXgi.js} +0 -0
  446. /package/dist/assets/{defaultLocale-q7sRUXPc.js → defaultLocale-USmzX3VG.js} +0 -0
  447. /package/dist/assets/{dist-DhMddrrH.js → dist-BYF6XVna.js} +0 -0
  448. /package/dist/assets/{graphlib-BM63WsW3.js → graphlib-DEFMkHdW.js} +0 -0
  449. /package/dist/assets/{host-capabilities-B107nwS3.js → host-capabilities-C0MmWd3M.js} +0 -0
  450. /package/dist/assets/{init-CRMkf9sL.js → init-04ErALoz.js} +0 -0
  451. /package/dist/assets/{jszip.min-6thm2J_a.js → jszip.min-BnQ5NRy2.js} +0 -0
  452. /package/dist/assets/{katex-B26hhTOT.js → katex-CsAM73R9.js} +0 -0
  453. /package/dist/assets/{middleware-0o3JF3tS.js → middleware-CAXxl-af.js} +0 -0
  454. /package/dist/assets/{panel-app-B39rJPj8.js → panel-app-2EACRB8p.js} +0 -0
  455. /package/dist/assets/{path-BFMmafCM.js → path-CzxQ9n2G.js} +0 -0
  456. /package/dist/assets/{rough.esm-5Tjchx1D.js → rough.esm-pT9fdsW3.js} +0 -0
  457. /package/dist/assets/{xlsx-BC8ibjXK.js → xlsx-BRpCSiE4.js} +0 -0
@@ -1,18 +1,10 @@
1
- import { useState, type PointerEvent } from "react";
1
+ import { PageResourceIcon } from '@/features/right-panel-resources';
2
2
  import {
3
- AppWindow,
4
3
  ArrowLeft,
5
4
  ArrowRight,
6
- BookOpen,
7
- Boxes,
8
- Github,
9
- PanelRightOpen,
10
- PictureInPicture2,
11
5
  Pin,
12
6
  PinOff,
13
7
  Plus,
14
- X,
15
- type LucideIcon,
16
8
  } from "lucide-react";
17
9
  import type { DocBrowserDockState, DocBrowserTab } from "./doc-browser-context";
18
10
  import type { ContextMenuGroup } from "@/shared/components/ui/context-menu/context-menu";
@@ -21,7 +13,6 @@ import {
21
13
  type CompactTabStripAction,
22
14
  type CompactTabStripTab,
23
15
  } from "@/shared/components/ui/tab-strip/compact-tab-strip";
24
- import { cn } from "@/shared/lib/utils";
25
16
  import { t } from "@/shared/lib/i18n";
26
17
 
27
18
  type DocBrowserTabStripProps = {
@@ -29,8 +20,6 @@ type DocBrowserTabStripProps = {
29
20
  activeTabId: string;
30
21
  canGoBack: boolean;
31
22
  canGoForward: boolean;
32
- isDocked: boolean;
33
- isFullscreen: boolean;
34
23
  dockState?: DocBrowserDockState;
35
24
  onGoBack: () => void;
36
25
  onGoForward: () => void;
@@ -38,78 +27,11 @@ type DocBrowserTabStripProps = {
38
27
  onToggleDock?: () => void;
39
28
  onSetActiveTab: (tabId: string) => void;
40
29
  onCloseTab: (tabId: string) => void;
41
- onClose: () => void;
42
- onDragStart: (event: PointerEvent<HTMLElement>) => void;
43
- onToggleMode: () => void;
44
30
  getTabMenuGroups?: (tab: DocBrowserTab) => readonly ContextMenuGroup[] | undefined;
45
31
  };
46
32
 
47
- const DOC_BROWSER_BUILTIN_TAB_ICONS: Record<string, LucideIcon> = {
48
- apps: Boxes,
49
- docs: BookOpen,
50
- github: Github,
51
- "new-tab": Plus,
52
- "panel-app": AppWindow,
53
- "service-apps": AppWindow,
54
- };
55
-
56
- function DocBrowserUrlTabIcon({
57
- fallbackIcon: FallbackIcon,
58
- url,
59
- }: {
60
- fallbackIcon: LucideIcon;
61
- url: string;
62
- }) {
63
- const [loadFailed, setLoadFailed] = useState(false);
64
- return loadFailed ? (
65
- <FallbackIcon className="h-3.5 w-3.5 text-muted-foreground" aria-hidden="true" />
66
- ) : (
67
- <img
68
- src={url}
69
- alt=""
70
- className="h-3.5 w-3.5 rounded-sm object-cover"
71
- onError={() => setLoadFailed(true)}
72
- />
73
- );
74
- }
75
-
76
33
  function DocBrowserTabIcon({ tab }: { tab: DocBrowserTab }) {
77
- const { dockIcon } = tab;
78
- const fallbackIcon = tab.kind === "docs"
79
- ? BookOpen
80
- : tab.kind === "home"
81
- ? Plus
82
- : tab.kind === "apps"
83
- ? Boxes
84
- : AppWindow;
85
- const Icon = dockIcon?.type === "builtin"
86
- ? (DOC_BROWSER_BUILTIN_TAB_ICONS[dockIcon.name] ?? fallbackIcon)
87
- : fallbackIcon;
88
-
89
- if (dockIcon?.type === "url") {
90
- return (
91
- <DocBrowserUrlTabIcon
92
- key={dockIcon.url}
93
- fallbackIcon={fallbackIcon}
94
- url={dockIcon.url}
95
- />
96
- );
97
- }
98
- if (dockIcon?.type === "text") {
99
- return (
100
- <span className="max-w-3.5 truncate text-[10px] font-semibold leading-none" aria-hidden="true">
101
- {dockIcon.value}
102
- </span>
103
- );
104
- }
105
-
106
- return <Icon className="h-3.5 w-3.5 text-muted-foreground" aria-hidden="true" />;
107
- }
108
-
109
- function shouldBlockHeaderDrag(target: EventTarget | null): boolean {
110
- return target instanceof Element && Boolean(
111
- target.closest("button, a, input, textarea, select, [data-compact-tab-item]"),
112
- );
34
+ return <PageResourceIcon uri={tab.resourceUri ?? tab.currentUrl} icon={tab.dockIcon} />;
113
35
  }
114
36
 
115
37
  export function DocBrowserTabStrip({
@@ -117,8 +39,6 @@ export function DocBrowserTabStrip({
117
39
  activeTabId,
118
40
  canGoBack,
119
41
  canGoForward,
120
- isDocked,
121
- isFullscreen,
122
42
  dockState,
123
43
  onGoBack,
124
44
  onGoForward,
@@ -126,21 +46,16 @@ export function DocBrowserTabStrip({
126
46
  onToggleDock,
127
47
  onSetActiveTab,
128
48
  onCloseTab,
129
- onClose,
130
- onDragStart,
131
- onToggleMode,
132
49
  getTabMenuGroups,
133
50
  }: DocBrowserTabStripProps) {
134
51
  const backLabel = t("docBrowserBack");
135
- const closeLabel = t("docBrowserClose");
136
- const closeTabLabel = t("docBrowserCloseTab");
52
+ const closeTabLabel = t("workbenchCloseTab");
137
53
  const dockLabel = dockState?.isDocked
138
54
  ? dockState.removable
139
55
  ? t("sideDockUnpinCurrent")
140
56
  : t("sideDockBuiltInDocked")
141
57
  : t("sideDockPinCurrent");
142
58
  const forwardLabel = t("docBrowserForward");
143
- const modeLabel = isDocked ? t("docBrowserFloatMode") : t("docBrowserDockMode");
144
59
  const newTabLabel = t("docBrowserNewTab");
145
60
  const compactTabs: CompactTabStripTab[] = tabs.map((tab) => ({
146
61
  key: tab.id,
@@ -170,17 +85,6 @@ export function DocBrowserTabStrip({
170
85
  },
171
86
  ]
172
87
  : []),
173
- ...(!isFullscreen
174
- ? [
175
- {
176
- key: "mode",
177
- icon: isDocked ? <PictureInPicture2 className="h-3.5 w-3.5" /> : <PanelRightOpen className="h-3.5 w-3.5" />,
178
- label: modeLabel,
179
- onClick: onToggleMode,
180
- },
181
- ]
182
- : []),
183
- { key: "close", icon: <X className="h-3.5 w-3.5" />, label: closeLabel, onClick: onClose },
184
88
  ];
185
89
 
186
90
  return (
@@ -189,14 +93,8 @@ export function DocBrowserTabStrip({
189
93
  actionsTestId="doc-browser-tab-actions"
190
94
  tabs={compactTabs}
191
95
  actions={actions}
192
- className={cn(
193
- "h-10 gap-1.5 border-border/50 bg-card/80 px-2 shrink-0 select-none",
194
- isFullscreen && "h-[calc(env(safe-area-inset-top,0px)+2.5rem)] pt-[env(safe-area-inset-top,0px)]",
195
- )}
196
- scrollClassName={cn(
197
- "doc-browser-tab-scrollbar flex h-full items-center gap-0.5",
198
- !isDocked && !isFullscreen && "cursor-grab active:cursor-grabbing",
199
- )}
96
+ className="h-10 min-w-0 flex-1 gap-1 border-0 bg-transparent px-0 select-none"
97
+ scrollClassName="doc-browser-tab-scrollbar flex h-full items-center gap-0.5"
200
98
  tabsClassName="items-center gap-0.5"
201
99
  actionsClassName="h-full items-center gap-0.5"
202
100
  actionButtonClassName="rounded-md p-1.5 text-muted-foreground hover:bg-muted/60 hover:text-foreground disabled:opacity-50"
@@ -204,17 +102,7 @@ export function DocBrowserTabStrip({
204
102
  activeTabClassName="bg-muted/80 text-foreground"
205
103
  inactiveTabClassName="text-muted-foreground hover:bg-muted/45 hover:text-foreground"
206
104
  labelClassName="px-0.5 text-xs font-normal"
207
- onPointerDown={!isDocked && !isFullscreen ? onDragStart : undefined}
208
- onScrollPointerDown={(event) => {
209
- if (shouldBlockHeaderDrag(event.target)) {
210
- event.stopPropagation();
211
- return;
212
- }
213
- if (!isDocked && !isFullscreen) {
214
- event.stopPropagation();
215
- onDragStart(event);
216
- }
217
- }}
105
+
218
106
  />
219
107
  );
220
108
  }
@@ -18,18 +18,11 @@ import {
18
18
  DocBrowserFrameContent,
19
19
  } from './doc-browser-panel-parts';
20
20
  import { DocBrowserTabStrip } from './doc-browser-tab-strip';
21
- import {
22
- createInitialFloatingPanelRect,
23
- moveFloatingPanelRect,
24
- resizeFloatingPanelRect,
25
- type FloatingPanelRect,
26
- type FloatingPanelResizeEdge,
27
- } from './utils/doc-browser-floating-panel.utils';
28
- import { ResizableRightPanel } from '@/shared/components/resizable-right-panel/resizable-right-panel';
29
- import { cn } from '@/shared/lib/utils';
21
+ import { WorkbenchSurface } from '@/shared/components/workbench/workbench-surface';
22
+ import { GLOBAL_WORKBENCH_SURFACE } from '@/shared/components/workbench/types/workbench-surface.types';
23
+ import { getAppPresenter } from '@/app/presenters/app.presenter';
30
24
  import { t } from '@/shared/lib/i18n';
31
25
  import type { ContextMenuGroup } from '@/shared/components/ui/context-menu/context-menu';
32
- import { GripVertical } from 'lucide-react';
33
26
  import {
34
27
  DOC_BROWSER_DOCKED_MAX_WIDTH,
35
28
  DOC_BROWSER_DOCKED_MIN_WIDTH,
@@ -44,16 +37,8 @@ type DocBrowserProps = {
44
37
 
45
38
  export type DocBrowserTabMenuGroupsResolver = NonNullable<DocBrowserProps['getTabMenuGroups']>;
46
39
 
47
- type FloatingPanelInteraction = {
48
- startX: number;
49
- startY: number;
50
- startRect: FloatingPanelRect;
51
- } & (
52
- | { kind: 'drag' }
53
- | { kind: 'resize'; edge: FloatingPanelResizeEdge }
54
- );
55
40
 
56
- const DEFAULT_DOCS_IFRAME_SANDBOX = 'allow-same-origin allow-scripts allow-popups allow-forms';
41
+
57
42
 
58
43
  function resolveContentUrlInput(input: string, currentUrl: string): string {
59
44
  if (input.startsWith('/')) {
@@ -72,20 +57,6 @@ function resolveContentUrlInput(input: string, currentUrl: string): string {
72
57
  return `https://${input}`;
73
58
  }
74
59
 
75
- function resolveIframeSandbox(
76
- customRenderer: DocBrowserCustomTabRenderers[string] | undefined,
77
- currentTab: DocBrowserTab | undefined,
78
- ): string | undefined {
79
- if (!currentTab) {
80
- return DEFAULT_DOCS_IFRAME_SANDBOX;
81
- }
82
- const customSandbox = customRenderer?.getIframeSandbox?.(currentTab);
83
- if (customSandbox !== undefined) {
84
- return customSandbox;
85
- }
86
- return currentTab.kind === 'content' ? undefined : DEFAULT_DOCS_IFRAME_SANDBOX;
87
- }
88
-
89
60
  function useDocBrowserDockAction(
90
61
  dockControls: DocBrowserDockControls | undefined,
91
62
  currentTab: DocBrowserTab | undefined,
@@ -172,7 +143,6 @@ export function DocBrowser({
172
143
  }: DocBrowserProps) {
173
144
  const {
174
145
  isOpen,
175
- mode,
176
146
  dockedWidth,
177
147
  tabs,
178
148
  activeTabId,
@@ -183,7 +153,6 @@ export function DocBrowser({
183
153
  openTarget,
184
154
  openNewTab,
185
155
  close,
186
- toggleMode,
187
156
  setDockedWidth,
188
157
  goBack,
189
158
  goForward,
@@ -194,8 +163,6 @@ export function DocBrowser({
194
163
  } = useDocBrowser();
195
164
 
196
165
  const [iframeReloadVersion, setIframeReloadVersion] = useState(0);
197
- const [floatRect, setFloatRect] = useState<FloatingPanelRect>(createInitialFloatingPanelRect);
198
- const [floatInteraction, setFloatInteraction] = useState<FloatingPanelInteraction | null>(null);
199
166
  const iframeRef = useRef<HTMLIFrameElement>(null);
200
167
  const currentUrl = currentTab?.currentUrl ?? getDefaultDocsUrl();
201
168
  const navVersion = currentTab?.navVersion ?? 0;
@@ -251,7 +218,7 @@ export function DocBrowser({
251
218
 
252
219
  useEffect(() => {
253
220
  const handler = (e: MessageEvent) => {
254
- if (!isDocsTab) {
221
+ if (!isDocsTab || e.source !== iframeRef.current?.contentWindow) {
255
222
  return;
256
223
  }
257
224
  if (e.data?.type === 'docs-route-change' && typeof e.data.url === 'string') {
@@ -283,65 +250,13 @@ export function DocBrowser({
283
250
  return () => window.removeEventListener('message', handler);
284
251
  }, [currentTab, customRenderer, iframeInstanceId]);
285
252
 
286
- const startFloatDrag = useCallback((event: React.PointerEvent<HTMLElement>) => {
287
- event.preventDefault();
288
- setFloatInteraction({
289
- kind: 'drag',
290
- startX: event.clientX,
291
- startY: event.clientY,
292
- startRect: floatRect,
293
- });
294
- }, [floatRect]);
295
-
296
- const startFloatResize = useCallback((edge: FloatingPanelResizeEdge) => (event: React.PointerEvent<HTMLElement>) => {
297
- event.preventDefault();
298
- event.stopPropagation();
299
- setFloatInteraction({
300
- kind: 'resize',
301
- edge,
302
- startX: event.clientX,
303
- startY: event.clientY,
304
- startRect: floatRect,
305
- });
306
- }, [floatRect]);
307
-
308
- useEffect(() => {
309
- if (!floatInteraction) return;
310
-
311
- const onMove = (event: PointerEvent) => {
312
- const { startRect, startX, startY } = floatInteraction;
313
- const dx = event.clientX - startX;
314
- const dy = event.clientY - startY;
315
-
316
- if (floatInteraction.kind === 'drag') {
317
- setFloatRect(moveFloatingPanelRect(startRect, dx, dy));
318
- return;
319
- }
320
-
321
- setFloatRect(resizeFloatingPanelRect(floatInteraction.edge, startRect, dx, dy));
322
- };
323
-
324
- const onEnd = () => setFloatInteraction(null);
325
-
326
- window.addEventListener('pointermove', onMove);
327
- window.addEventListener('pointerup', onEnd);
328
- window.addEventListener('pointercancel', onEnd);
329
- return () => {
330
- window.removeEventListener('pointermove', onMove);
331
- window.removeEventListener('pointerup', onEnd);
332
- window.removeEventListener('pointercancel', onEnd);
333
- };
334
- }, [floatInteraction]);
335
-
336
253
  const refreshIframe = useCallback(() => {
337
254
  setIframeReloadVersion((version) => version + 1);
338
255
  }, []);
339
256
 
340
257
  const handleToggleDock = useDocBrowserDockAction(dockControls, currentTab, dockState);
341
258
 
342
- if (!isOpen) return null;
343
259
 
344
- const isDocked = mode === 'docked';
345
260
  const isFullscreen = displayMode === 'fullscreen';
346
261
  const customRenderParams = currentTab ? {
347
262
  currentUrl,
@@ -354,29 +269,11 @@ export function DocBrowser({
354
269
  const customContent = customRenderParams
355
270
  ? customRenderer?.renderContent?.(customRenderParams) ?? (isHomeTab ? <DocBrowserHomePage /> : null)
356
271
  : null;
357
- const iframeSandbox = resolveIframeSandbox(customRenderer, currentTab);
272
+ const iframeSandbox = currentTab ? customRenderer?.getIframeSandbox?.(currentTab) : undefined;
358
273
 
359
274
  const panelContent = (
360
275
  <>
361
- <DocBrowserTabStrip
362
- tabs={tabs}
363
- activeTabId={activeTabId}
364
- canGoBack={canGoBack}
365
- canGoForward={canGoForward}
366
- dockState={dockState}
367
- isDocked={isDocked}
368
- isFullscreen={isFullscreen}
369
- onGoBack={goBack}
370
- onGoForward={goForward}
371
- onOpenNewTab={openNewTab}
372
- onToggleDock={handleToggleDock}
373
- onSetActiveTab={setActiveTab}
374
- onCloseTab={closeTab}
375
- onClose={close}
376
- onDragStart={startFloatDrag}
377
- onToggleMode={toggleMode}
378
- getTabMenuGroups={getTabMenuGroups}
379
- />
276
+
380
277
 
381
278
  <DocBrowserAddressToolbar
382
279
  isVisible={isAddressToolbarTab}
@@ -396,8 +293,8 @@ export function DocBrowser({
396
293
  iframeRef={iframeRef}
397
294
  iframeInstanceId={iframeInstanceId}
398
295
  iframeSandbox={iframeSandbox}
399
- isDragging={floatInteraction?.kind === 'drag'}
400
- isResizing={floatInteraction?.kind === 'resize'}
296
+ isDragging={false}
297
+ isResizing={false}
401
298
  onIframeLoad={restoreScroll}
402
299
  onIframePointerOver={customRenderer?.onIframePointerOver}
403
300
  />
@@ -406,89 +303,28 @@ export function DocBrowser({
406
303
  </>
407
304
  );
408
305
 
409
- if (isDocked && !isFullscreen) {
410
- return (
411
- <ResizableRightPanel
412
- data-testid="doc-browser-panel"
413
- data-theme-surface="doc-browser"
414
- defaultWidth={dockedWidth}
415
- width={dockedWidth}
416
- minWidth={DOC_BROWSER_DOCKED_MIN_WIDTH}
417
- maxWidth={DOC_BROWSER_DOCKED_MAX_WIDTH}
418
- onWidthCommit={setDockedWidth}
419
- >
420
- {panelContent}
421
- </ResizableRightPanel>
422
- );
423
- }
424
-
425
306
  return (
426
- <div
427
- data-testid="doc-browser-panel"
428
- data-theme-surface="doc-browser"
429
- className={cn(
430
- 'relative flex flex-col overflow-hidden bg-card text-card-foreground',
431
- isFullscreen
432
- ? 'fixed inset-0 z-[var(--z-floating-panel)] h-[100dvh] w-screen rounded-none border-0 shadow-2xl'
433
- : 'rounded-2xl border border-border shadow-2xl',
434
- )}
435
- style={
436
- isFullscreen
437
- ? undefined
438
- : {
439
- position: 'fixed',
440
- left: floatRect.x,
441
- top: floatRect.y,
442
- width: floatRect.w,
443
- height: floatRect.h,
444
- zIndex: 'var(--z-floating-panel)',
445
- }
446
- }
447
- >
307
+ <WorkbenchSurface id={GLOBAL_WORKBENCH_SURFACE} manager={getAppPresenter().workbenchSurfaceManager}
308
+ title={currentTab?.title || t('workbenchGlobalGroup')} testId="doc-browser-panel"
309
+ width={dockedWidth} minWidth={DOC_BROWSER_DOCKED_MIN_WIDTH} maxWidth={DOC_BROWSER_DOCKED_MAX_WIDTH}
310
+ onWidthCommit={setDockedWidth} onClose={close} closeLabel={t('workbenchHideGroup')}
311
+ hidden={!isOpen} fullscreen={isFullscreen} navigation={
312
+ <DocBrowserTabStrip
313
+ tabs={tabs}
314
+ activeTabId={activeTabId}
315
+ canGoBack={canGoBack}
316
+ canGoForward={canGoForward}
317
+ dockState={dockState}
318
+ onGoBack={goBack}
319
+ onGoForward={goForward}
320
+ onOpenNewTab={openNewTab}
321
+ onToggleDock={handleToggleDock}
322
+ onSetActiveTab={setActiveTab}
323
+ onCloseTab={closeTab}
324
+ getTabMenuGroups={getTabMenuGroups}
325
+ />
326
+ }>
448
327
  {panelContent}
449
-
450
- {!isDocked && !isFullscreen && (
451
- <>
452
- <div className="absolute top-0 left-0 h-3 w-full cursor-ns-resize z-20 hover:bg-primary/10 transition-colors" data-testid="doc-browser-resize-top" onPointerDown={startFloatResize('top')} />
453
- <div
454
- className="absolute top-0 left-0 w-3 h-full cursor-ew-resize z-20 hover:bg-primary/10 transition-colors"
455
- data-testid="doc-browser-resize-left"
456
- onPointerDown={startFloatResize('left')}
457
- />
458
- <div
459
- className="absolute top-0 right-0 w-3 h-full cursor-ew-resize z-20 hover:bg-primary/10 transition-colors"
460
- data-testid="doc-browser-resize-right"
461
- onPointerDown={startFloatResize('right')}
462
- />
463
- <div
464
- className="absolute bottom-0 left-0 h-3 w-full cursor-ns-resize z-20 hover:bg-primary/10 transition-colors"
465
- data-testid="doc-browser-resize-bottom"
466
- onPointerDown={startFloatResize('bottom')}
467
- />
468
- <div
469
- className="absolute top-0 left-0 z-30 h-4 w-4 cursor-nw-resize hover:bg-primary/10 transition-colors"
470
- data-testid="doc-browser-resize-top-left"
471
- onPointerDown={startFloatResize('top-left')}
472
- />
473
- <div
474
- className="absolute top-0 right-0 z-30 h-4 w-4 cursor-ne-resize hover:bg-primary/10 transition-colors"
475
- data-testid="doc-browser-resize-top-right"
476
- onPointerDown={startFloatResize('top-right')}
477
- />
478
- <div
479
- className="absolute bottom-0 left-0 z-30 h-4 w-4 cursor-sw-resize hover:bg-primary/10 transition-colors"
480
- data-testid="doc-browser-resize-bottom-left"
481
- onPointerDown={startFloatResize('bottom-left')}
482
- />
483
- <div
484
- className="absolute bottom-0 right-0 z-30 flex h-4 w-4 cursor-se-resize items-center justify-center text-muted-foreground/45 transition-colors hover:text-muted-foreground"
485
- data-testid="doc-browser-resize-bottom-right"
486
- onPointerDown={startFloatResize('bottom-right')}
487
- >
488
- <GripVertical className="w-3 h-3 rotate-[-45deg]" />
489
- </div>
490
- </>
491
- )}
492
- </div>
328
+ </WorkbenchSurface>
493
329
  );
494
330
  }
@@ -17,6 +17,6 @@ export function useDocBrowserScrollRestoration({
17
17
  currentUrl: currentTab?.currentUrl ?? null,
18
18
  iframeRef,
19
19
  isEnabled,
20
- restorationKey: currentTab ? `panel-app:doc-browser:${currentTab.id}` : null,
20
+ restorationKey: currentTab ? `panel-app:resource:${currentTab.dedupeKey ?? currentTab.resourceUri ?? currentTab.currentUrl}` : null,
21
21
  });
22
22
  }
@@ -1,3 +1,5 @@
1
+ import type { WorkbenchSurfaceManager } from '@/shared/components/workbench/managers/workbench-surface.manager';
2
+ import { GLOBAL_WORKBENCH_SURFACE } from '@/shared/components/workbench/types/workbench-surface.types';
1
3
  import type {
2
4
  DocBrowserActiveHistoryEntry,
3
5
  DocBrowserOpenOptions,
@@ -187,6 +189,7 @@ function openResolvedDocBrowserState(
187
189
  target.resourceUri ?? target.url,
188
190
  options?.dockIcon ?? target.dockIcon,
189
191
  target.contentParams,
192
+ options?.viewState ?? target.viewState,
190
193
  );
191
194
  if (isClosedDefaultHomeState(prev, activeTab)) {
192
195
  const nextState = {
@@ -244,6 +247,7 @@ function openDocBrowserState(
244
247
 
245
248
  export class DocBrowserManager {
246
249
  constructor(
250
+ private readonly surfaces: WorkbenchSurfaceManager,
247
251
  private readonly routeResolver: DocBrowserRouteResolver = defaultDocBrowserRouteResolver,
248
252
  private readonly onRightPanelOpened?: RightPanelOpenedHandler,
249
253
  ) {}
@@ -254,6 +258,8 @@ export class DocBrowserManager {
254
258
 
255
259
  readonly open = (url?: string, options?: DocBrowserOpenOptions): void => {
256
260
  this.setSnapshot((prev) => openDocBrowserState(this.routeResolver, prev, url, options));
261
+ if (options?.placement) this.surfaces.place(GLOBAL_WORKBENCH_SURFACE, options.placement);
262
+ this.surfaces.restore(GLOBAL_WORKBENCH_SURFACE);
257
263
  this.onRightPanelOpened?.();
258
264
  };
259
265
 
@@ -264,6 +270,8 @@ export class DocBrowserManager {
264
270
  kind: options?.kind ?? target.kind,
265
271
  title: options?.title ?? target.title,
266
272
  }));
273
+ if (options?.placement) this.surfaces.place(GLOBAL_WORKBENCH_SURFACE, options.placement);
274
+ this.surfaces.restore(GLOBAL_WORKBENCH_SURFACE);
267
275
  this.onRightPanelOpened?.();
268
276
  };
269
277
 
@@ -289,7 +297,9 @@ export class DocBrowserManager {
289
297
  };
290
298
 
291
299
  readonly toggleMode = (): void => {
292
- this.setSnapshot((prev) => ({ ...prev, mode: prev.mode === 'floating' ? 'docked' : 'floating' }));
300
+ const { surfaces } = this;
301
+ surfaces.place(GLOBAL_WORKBENCH_SURFACE, surfaces.get(GLOBAL_WORKBENCH_SURFACE).placement === 'floating' ? 'docked' : 'floating');
302
+ this.surfaces.restore(GLOBAL_WORKBENCH_SURFACE);
293
303
  this.onRightPanelOpened?.();
294
304
  };
295
305
 
@@ -1,9 +1,9 @@
1
+ import { ViewMemoryStorage } from '@/shared/lib/navigation-history';
1
2
  import { create } from 'zustand';
2
3
  import { createJSONStorage, persist } from 'zustand/middleware';
3
4
  import type {
4
5
  DocBrowserActiveHistoryEntry,
5
6
  DocBrowserDockIcon,
6
- DocBrowserMode,
7
7
  DocBrowserState,
8
8
  DocBrowserStateUpdate,
9
9
  DocBrowserTab,
@@ -28,9 +28,6 @@ function isRecord(value: unknown): value is Record<string, unknown> {
28
28
  return !!value && typeof value === 'object';
29
29
  }
30
30
 
31
- function isDocBrowserMode(value: unknown): value is DocBrowserMode {
32
- return value === 'floating' || value === 'docked';
33
- }
34
31
 
35
32
  function normalizePersistedStringList(value: unknown, fallback: string): string[] {
36
33
  if (!Array.isArray(value)) {
@@ -91,6 +88,7 @@ function normalizePersistedDocBrowserTab(value: unknown): DocBrowserTab | null {
91
88
  currentUrl: history[historyIndex] ?? value.currentUrl,
92
89
  resourceUri,
93
90
  dockIcon,
91
+ viewState: value.viewState,
94
92
  dedupeKey,
95
93
  history,
96
94
  historyIndex,
@@ -170,7 +168,6 @@ function normalizePersistedDocBrowserState(value: unknown): DocBrowserState | nu
170
168
 
171
169
  return {
172
170
  isOpen: value.isOpen === true,
173
- mode: isDocBrowserMode(value.mode) ? value.mode : 'docked',
174
171
  dockedWidth: normalizeDocBrowserDockedWidth(value.dockedWidth),
175
172
  tabs,
176
173
  activeTabId: resolvedActiveTabId,
@@ -197,11 +194,10 @@ export const useDocBrowserStore = create<DocBrowserStore>()(
197
194
  {
198
195
  name: DOC_BROWSER_STORAGE_KEY,
199
196
  version: DOC_BROWSER_STORAGE_VERSION,
200
- storage: createJSONStorage(() => window.localStorage),
197
+ storage: createJSONStorage(() => new ViewMemoryStorage()),
201
198
  partialize: (state): { snapshot: PersistedDocBrowserState } => ({
202
199
  snapshot: {
203
200
  isOpen: state.snapshot.isOpen,
204
- mode: state.snapshot.mode,
205
201
  dockedWidth: state.snapshot.dockedWidth,
206
202
  tabs: state.snapshot.tabs.slice(-DOC_BROWSER_MAX_PERSISTED_TABS),
207
203
  activeTabId: state.snapshot.activeTabId,
@@ -10,6 +10,8 @@ export type DocBrowserTab = {
10
10
  currentUrl: string;
11
11
  resourceUri?: string;
12
12
  contentParams?: UiContentParams;
13
+ /** Serializable renderer-owned view context; validated by the renderer. */
14
+ viewState?: unknown;
13
15
  dockIcon?: DocBrowserDockIcon;
14
16
  dedupeKey?: string;
15
17
  history: string[];
@@ -25,6 +27,8 @@ export type DocBrowserRouteTarget = {
25
27
  kind: DocBrowserTabKind;
26
28
  resourceUri?: string;
27
29
  contentParams?: UiContentParams;
30
+ /** Serializable renderer-owned view context; validated by the renderer. */
31
+ viewState?: unknown;
28
32
  title: string;
29
33
  url: string;
30
34
  };
@@ -69,6 +73,7 @@ export type DocBrowserActiveHistoryEntry = {
69
73
  };
70
74
 
71
75
  export type DocBrowserOpenOptions = {
76
+ placement?: DocBrowserMode;
72
77
  activate?: boolean;
73
78
  dedupeKey?: string;
74
79
  dockIcon?: DocBrowserDockIcon;
@@ -76,11 +81,12 @@ export type DocBrowserOpenOptions = {
76
81
  title?: string;
77
82
  kind?: DocBrowserTabKind;
78
83
  contentParams?: UiContentParams;
84
+ /** Serializable renderer-owned view context; validated by the renderer. */
85
+ viewState?: unknown;
79
86
  };
80
87
 
81
88
  export type DocBrowserState = {
82
89
  isOpen: boolean;
83
- mode: DocBrowserMode;
84
90
  dockedWidth: number;
85
91
  tabs: DocBrowserTab[];
86
92
  activeTabId: string;
@@ -106,5 +112,6 @@ export type DocBrowserActions = {
106
112
  };
107
113
 
108
114
  export type DocBrowserContextValue = DocBrowserState & DocBrowserActions & {
115
+ mode: DocBrowserMode;
109
116
  currentTab?: DocBrowserTab;
110
117
  };