@nextclaw/ui 0.13.3 → 0.13.5

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 (132) hide show
  1. package/CHANGELOG.md +128 -0
  2. package/dist/assets/api-BAyyGaoz.js +15 -0
  3. package/dist/assets/app-presenter-provider-DqHHfC1K.js +3 -0
  4. package/dist/assets/arrow-left-Bn-3Pj3p.js +1 -0
  5. package/dist/assets/{boxes-BvA-I63l.js → boxes-ClVuotcz.js} +1 -1
  6. package/dist/assets/channels-list-page-BnGxv6ma.js +8 -0
  7. package/dist/assets/chat-page-DInyWLb4.js +105 -0
  8. package/dist/assets/config-split-page-CWN2YG9U.js +1 -0
  9. package/dist/assets/confirm-dialog-CVbgKuHp.js +5 -0
  10. package/dist/assets/{createLucideIcon-Br1EFMEr.js → createLucideIcon-CjPUPAAK.js} +1 -1
  11. package/dist/assets/desktop-update-config-abmYzHSy.js +1 -0
  12. package/dist/assets/{dist-rzakR_bu.js → dist-hkrb6Ynt.js} +1 -1
  13. package/dist/assets/doc-browser-BlrpUKVJ.js +1 -0
  14. package/dist/assets/doc-browser-context-Cb1sEUT0.js +1 -0
  15. package/dist/assets/doc-browser-kJ2ClG0H.js +1 -0
  16. package/dist/assets/ellipsis-CdkxFkVZ.js +1 -0
  17. package/dist/assets/{external-link-DHjFdCpy.js → external-link-CT9_qFwN.js} +1 -1
  18. package/dist/assets/index-BGXTR0F_.css +1 -0
  19. package/dist/assets/index-Ccbswzt9.js +101 -0
  20. package/dist/assets/{key-round-D41Oe35x.js → key-round-xJfR4iRe.js} +1 -1
  21. package/dist/assets/{book-open-CRotBOF2.js → loader-circle-BI6HJDg5.js} +1 -1
  22. package/dist/assets/{mcp-marketplace-page-Dvi8mCBd.js → mcp-marketplace-page-CmUKUeno.js} +2 -2
  23. package/dist/assets/mcp-marketplace-page-DH11bSVx.js +1 -0
  24. package/dist/assets/model-config-Dbo3zWDl.js +1 -0
  25. package/dist/assets/notice-card-CFTFtJky.js +1 -0
  26. package/dist/assets/play-DyBWW2j4.js +1 -0
  27. package/dist/assets/plus-BlnBmcKE.js +1 -0
  28. package/dist/assets/popover-DPqa_Mfb.js +1 -0
  29. package/dist/assets/provider-models-CXUgDxGR.js +1 -0
  30. package/dist/assets/provider-scoped-model-input-C6xL7zSJ.js +1 -0
  31. package/dist/assets/providers-list-DOj_7GL8.js +1 -0
  32. package/dist/assets/react-oAHNoVya.js +1 -0
  33. package/dist/assets/refresh-cw-o8NSmIYV.js +1 -0
  34. package/dist/assets/remote-fCE5fLsj.js +1 -0
  35. package/dist/assets/rotate-cw-DA8EqNAH.js +1 -0
  36. package/dist/assets/runtime-config-page-Dg8aEgWx.js +1 -0
  37. package/dist/assets/{save-aYdSdK97.js → save-D4-g0EAq.js} +1 -1
  38. package/dist/assets/search-G2cMn3M5.js +1 -0
  39. package/dist/assets/{search-config-G2O1fcRb.js → search-config-DAibVFGR.js} +1 -1
  40. package/dist/assets/{secrets-config-TenzxYbE.js → secrets-config-CoJzy13_.js} +2 -2
  41. package/dist/assets/{status-dot-BSMG7ZaC.js → status-dot-D8xx5ZR8.js} +1 -1
  42. package/dist/assets/{tabs-D1CjpWNX.js → tabs-DxmND60Q.js} +1 -1
  43. package/dist/assets/{tabs-custom-CRSN1ekg.js → tabs-custom-Cjo0bHw8.js} +1 -1
  44. package/dist/assets/{tag-chip-DEashiw6.js → tag-chip-DnNWFRMu.js} +1 -1
  45. package/dist/assets/{trash-2-DSWTsARW.js → trash-2-C9tc-9sQ.js} +1 -1
  46. package/dist/assets/x-DmLl2yG6.js +1 -0
  47. package/dist/index.html +24 -23
  48. package/dist/logos/mimo.svg +9 -0
  49. package/package.json +8 -8
  50. package/public/logos/mimo.svg +9 -0
  51. package/src/app/components/layout/app-layout.tsx +10 -2
  52. package/src/features/agents/components/agents-page.tsx +6 -4
  53. package/src/features/chat/hooks/use-ncp-chat-page-data.ts +17 -10
  54. package/src/features/marketplace/components/marketplace-list-card.tsx +22 -1
  55. package/src/features/marketplace/components/marketplace-page.tsx +3 -1
  56. package/src/features/marketplace/hooks/use-marketplace.ts +3 -1
  57. package/src/features/marketplace/utils/marketplace-installed-cache.utils.ts +8 -0
  58. package/src/features/right-panel-resources/configs/right-panel-resource-routes.config.ts +70 -6
  59. package/src/features/right-panel-resources/utils/right-panel-resource-route-resolver.utils.test.ts +25 -1
  60. package/src/features/right-panel-resources/utils/right-panel-resource-route-resolver.utils.ts +1 -1
  61. package/src/features/right-panel-resources/utils/right-panel-resource-uri.utils.test.ts +42 -0
  62. package/src/features/right-panel-resources/utils/right-panel-resource-uri.utils.ts +22 -0
  63. package/src/features/service-apps/components/service-apps-panel.test.tsx +88 -0
  64. package/src/features/service-apps/components/service-apps-panel.tsx +246 -56
  65. package/src/features/service-apps/hooks/use-service-apps.ts +14 -0
  66. package/src/features/side-dock/components/side-dock.test.tsx +58 -3
  67. package/src/features/side-dock/components/side-dock.tsx +77 -24
  68. package/src/features/side-dock/configs/side-dock-built-in-items.config.ts +37 -34
  69. package/src/features/side-dock/index.ts +2 -0
  70. package/src/features/side-dock/managers/side-dock.manager.test.ts +84 -3
  71. package/src/features/side-dock/managers/side-dock.manager.ts +135 -12
  72. package/src/features/side-dock/types/side-dock.types.ts +11 -4
  73. package/src/features/side-dock/utils/side-dock-item.utils.test.ts +8 -8
  74. package/src/features/side-dock/utils/side-dock-item.utils.ts +13 -5
  75. package/src/platforms/desktop/components/desktop-app-shell.tsx +5 -2
  76. package/src/platforms/mobile/components/mobile-app-shell.tsx +4 -1
  77. package/src/shared/components/config/provider-form-support.test.ts +21 -0
  78. package/src/shared/components/config/provider-form-support.ts +38 -78
  79. package/src/shared/components/config/provider-form.tsx +54 -67
  80. package/src/shared/components/config/providers-list.tsx +211 -73
  81. package/src/shared/components/doc-browser/doc-browser-context.test.tsx +73 -0
  82. package/src/shared/components/doc-browser/doc-browser-context.tsx +3 -0
  83. package/src/shared/components/doc-browser/doc-browser-tab-strip.tsx +25 -2
  84. package/src/shared/components/doc-browser/doc-browser.test.tsx +42 -0
  85. package/src/shared/components/doc-browser/doc-browser.tsx +38 -7
  86. package/src/shared/components/doc-browser/index.ts +1 -0
  87. package/src/shared/components/doc-browser/managers/doc-browser.manager.ts +30 -6
  88. package/src/shared/components/doc-browser/stores/doc-browser.store.ts +29 -0
  89. package/src/shared/components/doc-browser/types/doc-browser.types.ts +23 -0
  90. package/src/shared/components/doc-browser/utils/doc-browser-state.utils.ts +7 -0
  91. package/src/shared/components/model-config.tsx +5 -4
  92. package/src/shared/components/provider-auth-section.tsx +2 -2
  93. package/src/shared/components/ui/switch.tsx +5 -2
  94. package/src/shared/hooks/use-config.ts +27 -6
  95. package/src/shared/lib/api/marketplace.types.ts +193 -0
  96. package/src/shared/lib/api/types.ts +23 -200
  97. package/src/shared/lib/api/utils/config.utils.ts +17 -7
  98. package/src/shared/lib/i18n/index.ts +10 -12
  99. package/src/shared/lib/i18n/{marketplace.ts → marketplace-labels.utils.ts} +3 -0
  100. package/src/shared/lib/i18n/runtime/doc-browser-labels.utils.ts +46 -2
  101. package/src/shared/lib/provider-models/index.test.ts +93 -15
  102. package/src/shared/lib/provider-models/index.ts +35 -20
  103. package/src/shared/lib/transport/request-raw-api-response.utils.ts +1 -1
  104. package/dist/assets/api-DruAcori.js +0 -15
  105. package/dist/assets/app-presenter-provider-DIcnNB9s.js +0 -3
  106. package/dist/assets/channels-list-page-wK3l7p5R.js +0 -8
  107. package/dist/assets/chat-page-DgehvdJT.js +0 -105
  108. package/dist/assets/config-split-page-BnTO1mAM.js +0 -1
  109. package/dist/assets/confirm-dialog-CGrKHbAW.js +0 -5
  110. package/dist/assets/desktop-update-config-CehWxSSg.js +0 -1
  111. package/dist/assets/dist-CpwDZDtv.js +0 -1
  112. package/dist/assets/doc-browser-BgxmVsTx.js +0 -1
  113. package/dist/assets/doc-browser-CZn5-Qbu.js +0 -1
  114. package/dist/assets/doc-browser-context-B8gk7HMr.js +0 -1
  115. package/dist/assets/index-DORmh0Cy.css +0 -1
  116. package/dist/assets/index-DcFpvnge.js +0 -101
  117. package/dist/assets/mcp-marketplace-page-DBLhJWOJ.js +0 -1
  118. package/dist/assets/model-config-B-EJXGtO.js +0 -1
  119. package/dist/assets/play-C-0vo7hi.js +0 -1
  120. package/dist/assets/plus-Cr_akLp2.js +0 -1
  121. package/dist/assets/popover-YieElO8c.js +0 -1
  122. package/dist/assets/provider-scoped-model-input-BPRNGqYn.js +0 -1
  123. package/dist/assets/providers-list-CtBpL1ZY.js +0 -1
  124. package/dist/assets/react-B2X_ph0a.js +0 -1
  125. package/dist/assets/remote-BGHbHoHf.js +0 -1
  126. package/dist/assets/rotate-cw-jueVCNJQ.js +0 -1
  127. package/dist/assets/runtime-config-page-C1Hv7mad.js +0 -1
  128. package/dist/assets/search-CdhgFNwf.js +0 -1
  129. package/dist/assets/setting-row-BNu0qhOM.js +0 -1
  130. package/dist/assets/x-D1v_vb54.js +0 -1
  131. package/src/shared/components/provider-enabled-field.tsx +0 -23
  132. /package/dist/assets/{config-hints-A7G_jMTU.js → config-hints-TmNgpFHv.js} +0 -0
package/dist/index.html CHANGED
@@ -78,29 +78,30 @@
78
78
  })();
79
79
  </script>
80
80
  <title>NextClaw</title>
81
- <script type="module" crossorigin src="/assets/index-DcFpvnge.js"></script>
82
- <link rel="modulepreload" crossorigin href="/assets/react-B2X_ph0a.js">
83
- <link rel="modulepreload" crossorigin href="/assets/api-DruAcori.js">
84
- <link rel="modulepreload" crossorigin href="/assets/dist-rzakR_bu.js">
85
- <link rel="modulepreload" crossorigin href="/assets/dist-CpwDZDtv.js">
86
- <link rel="modulepreload" crossorigin href="/assets/createLucideIcon-Br1EFMEr.js">
87
- <link rel="modulepreload" crossorigin href="/assets/x-D1v_vb54.js">
88
- <link rel="modulepreload" crossorigin href="/assets/confirm-dialog-CGrKHbAW.js">
89
- <link rel="modulepreload" crossorigin href="/assets/popover-YieElO8c.js">
90
- <link rel="modulepreload" crossorigin href="/assets/search-CdhgFNwf.js">
91
- <link rel="modulepreload" crossorigin href="/assets/book-open-CRotBOF2.js">
92
- <link rel="modulepreload" crossorigin href="/assets/boxes-BvA-I63l.js">
93
- <link rel="modulepreload" crossorigin href="/assets/key-round-D41Oe35x.js">
94
- <link rel="modulepreload" crossorigin href="/assets/plus-Cr_akLp2.js">
95
- <link rel="modulepreload" crossorigin href="/assets/rotate-cw-jueVCNJQ.js">
96
- <link rel="modulepreload" crossorigin href="/assets/trash-2-DSWTsARW.js">
97
- <link rel="modulepreload" crossorigin href="/assets/doc-browser-context-B8gk7HMr.js">
98
- <link rel="modulepreload" crossorigin href="/assets/status-dot-BSMG7ZaC.js">
99
- <link rel="modulepreload" crossorigin href="/assets/tabs-D1CjpWNX.js">
100
- <link rel="modulepreload" crossorigin href="/assets/app-presenter-provider-DIcnNB9s.js">
101
- <link rel="modulepreload" crossorigin href="/assets/external-link-DHjFdCpy.js">
102
- <link rel="modulepreload" crossorigin href="/assets/doc-browser-CZn5-Qbu.js">
103
- <link rel="stylesheet" crossorigin href="/assets/index-DORmh0Cy.css">
81
+ <script type="module" crossorigin src="/assets/index-Ccbswzt9.js"></script>
82
+ <link rel="modulepreload" crossorigin href="/assets/react-oAHNoVya.js">
83
+ <link rel="modulepreload" crossorigin href="/assets/api-BAyyGaoz.js">
84
+ <link rel="modulepreload" crossorigin href="/assets/dist-hkrb6Ynt.js">
85
+ <link rel="modulepreload" crossorigin href="/assets/createLucideIcon-CjPUPAAK.js">
86
+ <link rel="modulepreload" crossorigin href="/assets/x-DmLl2yG6.js">
87
+ <link rel="modulepreload" crossorigin href="/assets/confirm-dialog-CVbgKuHp.js">
88
+ <link rel="modulepreload" crossorigin href="/assets/popover-DPqa_Mfb.js">
89
+ <link rel="modulepreload" crossorigin href="/assets/arrow-left-Bn-3Pj3p.js">
90
+ <link rel="modulepreload" crossorigin href="/assets/loader-circle-BI6HJDg5.js">
91
+ <link rel="modulepreload" crossorigin href="/assets/boxes-ClVuotcz.js">
92
+ <link rel="modulepreload" crossorigin href="/assets/key-round-xJfR4iRe.js">
93
+ <link rel="modulepreload" crossorigin href="/assets/plus-BlnBmcKE.js">
94
+ <link rel="modulepreload" crossorigin href="/assets/refresh-cw-o8NSmIYV.js">
95
+ <link rel="modulepreload" crossorigin href="/assets/trash-2-C9tc-9sQ.js">
96
+ <link rel="modulepreload" crossorigin href="/assets/doc-browser-context-Cb1sEUT0.js">
97
+ <link rel="modulepreload" crossorigin href="/assets/notice-card-CFTFtJky.js">
98
+ <link rel="modulepreload" crossorigin href="/assets/status-dot-D8xx5ZR8.js">
99
+ <link rel="modulepreload" crossorigin href="/assets/tabs-DxmND60Q.js">
100
+ <link rel="modulepreload" crossorigin href="/assets/app-presenter-provider-DqHHfC1K.js">
101
+ <link rel="modulepreload" crossorigin href="/assets/external-link-CT9_qFwN.js">
102
+ <link rel="modulepreload" crossorigin href="/assets/search-G2cMn3M5.js">
103
+ <link rel="modulepreload" crossorigin href="/assets/doc-browser-kJ2ClG0H.js">
104
+ <link rel="stylesheet" crossorigin href="/assets/index-BGXTR0F_.css">
104
105
  </head>
105
106
 
106
107
  <body>
@@ -0,0 +1,9 @@
1
+ <svg width="439" height="56" viewBox="0 0 439 56" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M315.261 6.88082V50.7653C315.261 53.1848 313.301 55.1452 310.882 55.1452C308.462 55.1452 306.502 53.1848 306.502 50.7653V6.88082C306.502 4.46138 308.462 2.50094 310.882 2.50094C313.301 2.50094 315.261 4.46138 315.261 6.88082ZM247.733 22.4184C245.313 22.4184 243.353 24.3789 243.353 26.7983V50.8254C243.353 53.2448 245.313 55.2052 247.733 55.2052C250.152 55.2052 252.112 53.2448 252.112 50.8254V26.7983C252.112 24.3789 250.152 22.4184 247.733 22.4184ZM297.207 6.44755C297.203 6.38749 297.19 6.33172 297.181 6.27596C297.168 6.19016 297.16 6.10865 297.143 6.02286C297.13 5.95422 297.108 5.88559 297.091 5.82124C297.074 5.7526 297.057 5.67968 297.035 5.61104C297.014 5.5424 296.988 5.47806 296.967 5.40942C296.941 5.34078 296.92 5.27215 296.894 5.20351C296.868 5.13916 296.838 5.07911 296.808 5.01905C296.778 4.95041 296.744 4.88178 296.709 4.81314C296.679 4.75308 296.641 4.69731 296.606 4.64155C296.568 4.5772 296.529 4.50856 296.486 4.44422C296.443 4.37987 296.396 4.3241 296.353 4.26405C296.315 4.20828 296.276 4.15251 296.233 4.10104C296.143 3.9895 296.045 3.88226 295.942 3.7793C295.839 3.67635 295.731 3.58197 295.62 3.4876C295.568 3.4447 295.517 3.41038 295.465 3.37177C295.401 3.32458 295.341 3.2774 295.277 3.2345C295.217 3.1916 295.152 3.15728 295.088 3.12296C295.028 3.08865 294.968 3.05004 294.908 3.01572C294.844 2.9814 294.779 2.95137 294.715 2.92134C294.65 2.89132 294.586 2.857 294.518 2.83126C294.457 2.80552 294.393 2.78407 294.329 2.76262C294.256 2.73688 294.187 2.71114 294.114 2.68541C294.054 2.66825 293.99 2.65109 293.926 2.63822C293.848 2.61677 293.775 2.59961 293.698 2.58245C293.63 2.56958 293.561 2.561 293.488 2.55242C293.415 2.54384 293.346 2.52668 293.274 2.52239C293.153 2.50952 293.029 2.50523 292.909 2.50523C292.888 2.50523 292.866 2.50523 292.845 2.50523C292.819 2.50523 292.797 2.50523 292.772 2.50523C292.652 2.50523 292.532 2.50952 292.416 2.52239C292.339 2.53097 292.266 2.54384 292.193 2.55671C292.128 2.56529 292.06 2.57387 291.995 2.58674C291.914 2.6039 291.837 2.62535 291.755 2.6468C291.695 2.66396 291.635 2.67254 291.579 2.69399C291.502 2.71543 291.425 2.74546 291.352 2.77549C291.292 2.79694 291.232 2.8141 291.176 2.83984C291.103 2.86987 291.034 2.90418 290.966 2.9385C290.906 2.96853 290.846 2.99427 290.79 3.0243C290.721 3.06291 290.657 3.10151 290.588 3.14441C290.533 3.17873 290.477 3.20876 290.421 3.24737C290.344 3.29885 290.275 3.35461 290.202 3.40609C290.159 3.43612 290.117 3.46615 290.078 3.50046C289.962 3.59484 289.855 3.69351 289.752 3.79646L270.295 23.2549L250.834 3.79217C249.122 2.08055 246.351 2.08055 244.64 3.79217C242.928 5.50379 242.928 8.275 244.64 9.98662L267.198 32.5466C268.91 34.2582 271.681 34.2582 273.392 32.5466L288.474 17.4637V50.834C288.474 53.2534 290.434 55.2138 292.853 55.2138C295.272 55.2138 297.233 53.2534 297.233 50.834V6.88511C297.233 6.73925 297.224 6.5934 297.211 6.44755H297.207ZM328.915 22.4184C326.495 22.4184 324.535 24.3789 324.535 26.7983V50.8254C324.535 53.2448 326.495 55.2052 328.915 55.2052C331.334 55.2052 333.294 53.2448 333.294 50.8254V26.7983C333.294 24.3789 331.334 22.4184 328.915 22.4184ZM378.385 6.44755C378.38 6.38749 378.368 6.33172 378.359 6.27596C378.346 6.19445 378.338 6.10865 378.32 6.02715C378.308 5.95851 378.286 5.88987 378.269 5.82124C378.252 5.7526 378.235 5.67968 378.213 5.61104C378.192 5.5424 378.166 5.47806 378.145 5.40942C378.119 5.34078 378.097 5.27215 378.072 5.20351C378.046 5.13916 378.016 5.07911 377.986 5.01905C377.956 4.95041 377.921 4.88178 377.887 4.81314C377.857 4.75308 377.819 4.69731 377.784 4.64155C377.746 4.5772 377.707 4.50856 377.664 4.44422C377.621 4.37987 377.574 4.3241 377.531 4.26405C377.493 4.20828 377.454 4.15251 377.411 4.10104C377.321 3.9895 377.222 3.88226 377.119 3.7793C377.016 3.67635 376.909 3.58197 376.798 3.4876C376.746 3.4447 376.695 3.41038 376.643 3.37177C376.579 3.32458 376.519 3.2774 376.454 3.2345C376.394 3.1916 376.33 3.15728 376.266 3.12296C376.206 3.08865 376.146 3.05004 376.086 3.01572C376.021 2.9814 375.957 2.95137 375.893 2.92134C375.828 2.89132 375.764 2.857 375.695 2.83126C375.635 2.80552 375.571 2.78407 375.507 2.76262C375.434 2.73688 375.365 2.71114 375.288 2.68541C375.228 2.66825 375.163 2.65538 375.099 2.63822C375.022 2.61677 374.949 2.59961 374.872 2.58245C374.803 2.56958 374.734 2.561 374.661 2.55242C374.589 2.54384 374.52 2.52668 374.447 2.52239C374.327 2.50952 374.203 2.50523 374.082 2.50523C374.061 2.50523 374.04 2.50523 374.018 2.50523C373.992 2.50523 373.971 2.50523 373.945 2.50523C373.825 2.50523 373.705 2.50952 373.589 2.52239C373.512 2.53097 373.439 2.54384 373.366 2.55671C373.302 2.56529 373.233 2.57387 373.169 2.58674C373.087 2.6039 373.01 2.62535 372.929 2.6468C372.868 2.65967 372.808 2.67254 372.753 2.69399C372.675 2.71543 372.598 2.74546 372.525 2.77549C372.465 2.79694 372.41 2.8141 372.349 2.83984C372.277 2.86987 372.208 2.90418 372.139 2.9385C372.079 2.96853 372.019 2.99427 371.963 3.0243C371.895 3.06291 371.83 3.10151 371.762 3.14441C371.706 3.17873 371.65 3.20876 371.595 3.24737C371.517 3.29885 371.449 3.35461 371.376 3.40609C371.333 3.43612 371.29 3.46615 371.251 3.50046C371.136 3.59484 371.028 3.69351 370.925 3.79646L351.468 23.2549L332.007 3.79217C330.296 2.08055 327.525 2.08055 325.813 3.79217C324.102 5.50379 324.102 8.275 325.813 9.98662L348.371 32.5466C350.083 34.2582 352.854 34.2582 354.565 32.5466L369.647 17.4637V50.834C369.647 53.2534 371.607 55.2138 374.027 55.2138C376.446 55.2138 378.406 53.2534 378.406 50.834V6.88511C378.406 6.73925 378.398 6.5934 378.385 6.44755ZM30.4894 29.252L49.6889 5.45232H39.3428L25.2005 22.9032L11.0625 5.45232H0.716337L19.9159 29.252L19.9845 29.3421L0 53.9998H11.0282L25.2048 35.8883L39.3814 53.9998H50.4095L30.425 29.3421L30.4937 29.252H30.4894ZM59.0313 0C55.6984 0 53.528 2.46234 53.528 5.44803C53.528 8.43372 55.6984 10.8961 59.0313 10.8961C62.3642 10.8961 64.5347 8.43372 64.5347 5.44803C64.5347 2.46234 62.3642 0 59.0313 0ZM54.6518 53.9998H63.4109V15.4647H54.6518V53.9998ZM103.487 30.7277V53.9955H94.7281V50.1476C92.193 53.1333 88.3025 54.9479 82.293 54.9479C79.5349 54.9479 70.2482 53.3692 69.2231 44.0561C68.2408 35.1591 75.5886 29.1877 89.3448 29.1877H94.7281C94.7281 24.4604 92.5448 21.5476 86.6553 21.4361C81.8598 21.346 77.832 23.2463 74.868 25.8202L71.4192 19.2182C75.8974 15.3446 83.0136 13.0624 90.4601 13.9804C102.646 15.4818 103.487 25.55 103.487 30.7277ZM94.7281 36.3817H90.4472C81.2035 36.3817 77.729 39.3416 78.055 42.7134C78.3724 46.0122 81.3622 47.445 85.0254 47.445C91.2794 47.445 94.7281 41.3235 94.7281 37.4541V36.3774V36.3817ZM147.54 34.5885C147.54 45.875 139.819 55.1752 127.976 55.1752C116.132 55.1752 108.411 45.8793 108.411 34.5885C108.411 23.2978 116.132 14.0019 127.976 14.0019C139.819 14.0019 147.54 23.2978 147.54 34.5885ZM138.781 34.5885C138.781 26.5495 134.024 21.835 127.971 21.835C121.919 21.835 117.162 26.5495 117.162 34.5885C117.162 42.6276 121.919 47.3421 127.971 47.3421C134.024 47.3421 138.781 42.6276 138.781 34.5885ZM214.386 53.9998H223.145V15.4647H214.386V53.9998ZM218.766 0C215.433 0 213.263 2.46234 213.263 5.44803C213.263 8.43372 215.433 10.8961 218.766 10.8961C222.099 10.8961 224.269 8.43372 224.269 5.44803C224.269 2.46234 222.099 0 218.766 0ZM193.973 13.7788C188.512 13.7788 184.528 16.0352 182.357 20.8055C180.307 15.7135 176.009 13.7788 171.869 13.7788C168.112 13.7788 163.166 15.469 161.498 19.969V15.469H152.919V54.0041H161.678V31.0323C161.678 28.201 162.6 21.8522 168.635 21.8522C174.67 21.8522 175.683 28.201 175.683 31.0323V54.0041H184.442V31.0323C184.442 28.201 185.364 21.8522 191.489 21.8522C197.615 21.8522 198.447 28.201 198.447 31.0323V54.0041H207.206V28.9646C207.206 18.9265 201.205 13.7831 193.982 13.7831L193.973 13.7788ZM419.855 45.4202C412.958 48.7362 404.439 47.4407 398.863 41.8597C393.286 36.283 391.987 27.7635 395.302 20.8655C396.203 18.9952 395.615 16.743 393.951 15.499C391.721 13.8303 388.534 14.6367 387.337 17.1506C382.503 27.3302 384.433 39.8607 392.647 48.0756C400.861 56.2906 413.391 58.221 423.57 53.3864C426.083 52.1938 426.885 49.0022 425.221 46.7715C423.977 45.1071 421.725 44.5194 419.855 45.4202ZM431.076 9.64344C422.862 1.4285 410.333 -0.501905 400.154 4.33268C397.64 5.52524 396.838 8.71684 398.502 10.9475C399.746 12.612 401.998 13.1997 403.868 12.2988C410.766 8.98281 419.285 10.2783 424.861 15.8593C430.437 21.4361 431.737 29.9556 428.421 36.8535C427.52 38.7239 428.108 40.976 429.772 42.2201C432.003 43.8888 435.19 43.0823 436.387 40.5685C441.221 30.3888 439.291 17.8541 431.076 9.64344Z" fill="url(#paint0_linear_1_3217)"/>
3
+ <defs>
4
+ <linearGradient id="paint0_linear_1_3217" x1="438.916" y1="28" x2="4.5156e-08" y2="28" gradientUnits="userSpaceOnUse">
5
+ <stop offset="0.158366" stop-color="#3D3834"/>
6
+ <stop offset="1" stop-color="#736B68"/>
7
+ </linearGradient>
8
+ </defs>
9
+ </svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/ui",
3
- "version": "0.13.3",
3
+ "version": "0.13.5",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -28,13 +28,13 @@
28
28
  "tailwind-merge": "^2.5.4",
29
29
  "zod": "^3.23.8",
30
30
  "zustand": "^5.0.2",
31
- "@nextclaw/agent-chat": "0.2.3",
32
- "@nextclaw/agent-chat-ui": "0.4.3",
33
- "@nextclaw/ncp": "0.5.23",
34
- "@nextclaw/client-sdk": "0.2.3",
35
- "@nextclaw/ncp-http-agent-client": "0.3.35",
36
- "@nextclaw/shared": "0.2.3",
37
- "@nextclaw/ncp-react": "0.4.43"
31
+ "@nextclaw/ncp": "0.5.25",
32
+ "@nextclaw/client-sdk": "0.2.5",
33
+ "@nextclaw/ncp-http-agent-client": "0.3.37",
34
+ "@nextclaw/shared": "0.2.5",
35
+ "@nextclaw/agent-chat": "0.2.5",
36
+ "@nextclaw/agent-chat-ui": "0.4.5",
37
+ "@nextclaw/ncp-react": "0.4.45"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@testing-library/react": "^16.3.0",
@@ -0,0 +1,9 @@
1
+ <svg width="439" height="56" viewBox="0 0 439 56" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M315.261 6.88082V50.7653C315.261 53.1848 313.301 55.1452 310.882 55.1452C308.462 55.1452 306.502 53.1848 306.502 50.7653V6.88082C306.502 4.46138 308.462 2.50094 310.882 2.50094C313.301 2.50094 315.261 4.46138 315.261 6.88082ZM247.733 22.4184C245.313 22.4184 243.353 24.3789 243.353 26.7983V50.8254C243.353 53.2448 245.313 55.2052 247.733 55.2052C250.152 55.2052 252.112 53.2448 252.112 50.8254V26.7983C252.112 24.3789 250.152 22.4184 247.733 22.4184ZM297.207 6.44755C297.203 6.38749 297.19 6.33172 297.181 6.27596C297.168 6.19016 297.16 6.10865 297.143 6.02286C297.13 5.95422 297.108 5.88559 297.091 5.82124C297.074 5.7526 297.057 5.67968 297.035 5.61104C297.014 5.5424 296.988 5.47806 296.967 5.40942C296.941 5.34078 296.92 5.27215 296.894 5.20351C296.868 5.13916 296.838 5.07911 296.808 5.01905C296.778 4.95041 296.744 4.88178 296.709 4.81314C296.679 4.75308 296.641 4.69731 296.606 4.64155C296.568 4.5772 296.529 4.50856 296.486 4.44422C296.443 4.37987 296.396 4.3241 296.353 4.26405C296.315 4.20828 296.276 4.15251 296.233 4.10104C296.143 3.9895 296.045 3.88226 295.942 3.7793C295.839 3.67635 295.731 3.58197 295.62 3.4876C295.568 3.4447 295.517 3.41038 295.465 3.37177C295.401 3.32458 295.341 3.2774 295.277 3.2345C295.217 3.1916 295.152 3.15728 295.088 3.12296C295.028 3.08865 294.968 3.05004 294.908 3.01572C294.844 2.9814 294.779 2.95137 294.715 2.92134C294.65 2.89132 294.586 2.857 294.518 2.83126C294.457 2.80552 294.393 2.78407 294.329 2.76262C294.256 2.73688 294.187 2.71114 294.114 2.68541C294.054 2.66825 293.99 2.65109 293.926 2.63822C293.848 2.61677 293.775 2.59961 293.698 2.58245C293.63 2.56958 293.561 2.561 293.488 2.55242C293.415 2.54384 293.346 2.52668 293.274 2.52239C293.153 2.50952 293.029 2.50523 292.909 2.50523C292.888 2.50523 292.866 2.50523 292.845 2.50523C292.819 2.50523 292.797 2.50523 292.772 2.50523C292.652 2.50523 292.532 2.50952 292.416 2.52239C292.339 2.53097 292.266 2.54384 292.193 2.55671C292.128 2.56529 292.06 2.57387 291.995 2.58674C291.914 2.6039 291.837 2.62535 291.755 2.6468C291.695 2.66396 291.635 2.67254 291.579 2.69399C291.502 2.71543 291.425 2.74546 291.352 2.77549C291.292 2.79694 291.232 2.8141 291.176 2.83984C291.103 2.86987 291.034 2.90418 290.966 2.9385C290.906 2.96853 290.846 2.99427 290.79 3.0243C290.721 3.06291 290.657 3.10151 290.588 3.14441C290.533 3.17873 290.477 3.20876 290.421 3.24737C290.344 3.29885 290.275 3.35461 290.202 3.40609C290.159 3.43612 290.117 3.46615 290.078 3.50046C289.962 3.59484 289.855 3.69351 289.752 3.79646L270.295 23.2549L250.834 3.79217C249.122 2.08055 246.351 2.08055 244.64 3.79217C242.928 5.50379 242.928 8.275 244.64 9.98662L267.198 32.5466C268.91 34.2582 271.681 34.2582 273.392 32.5466L288.474 17.4637V50.834C288.474 53.2534 290.434 55.2138 292.853 55.2138C295.272 55.2138 297.233 53.2534 297.233 50.834V6.88511C297.233 6.73925 297.224 6.5934 297.211 6.44755H297.207ZM328.915 22.4184C326.495 22.4184 324.535 24.3789 324.535 26.7983V50.8254C324.535 53.2448 326.495 55.2052 328.915 55.2052C331.334 55.2052 333.294 53.2448 333.294 50.8254V26.7983C333.294 24.3789 331.334 22.4184 328.915 22.4184ZM378.385 6.44755C378.38 6.38749 378.368 6.33172 378.359 6.27596C378.346 6.19445 378.338 6.10865 378.32 6.02715C378.308 5.95851 378.286 5.88987 378.269 5.82124C378.252 5.7526 378.235 5.67968 378.213 5.61104C378.192 5.5424 378.166 5.47806 378.145 5.40942C378.119 5.34078 378.097 5.27215 378.072 5.20351C378.046 5.13916 378.016 5.07911 377.986 5.01905C377.956 4.95041 377.921 4.88178 377.887 4.81314C377.857 4.75308 377.819 4.69731 377.784 4.64155C377.746 4.5772 377.707 4.50856 377.664 4.44422C377.621 4.37987 377.574 4.3241 377.531 4.26405C377.493 4.20828 377.454 4.15251 377.411 4.10104C377.321 3.9895 377.222 3.88226 377.119 3.7793C377.016 3.67635 376.909 3.58197 376.798 3.4876C376.746 3.4447 376.695 3.41038 376.643 3.37177C376.579 3.32458 376.519 3.2774 376.454 3.2345C376.394 3.1916 376.33 3.15728 376.266 3.12296C376.206 3.08865 376.146 3.05004 376.086 3.01572C376.021 2.9814 375.957 2.95137 375.893 2.92134C375.828 2.89132 375.764 2.857 375.695 2.83126C375.635 2.80552 375.571 2.78407 375.507 2.76262C375.434 2.73688 375.365 2.71114 375.288 2.68541C375.228 2.66825 375.163 2.65538 375.099 2.63822C375.022 2.61677 374.949 2.59961 374.872 2.58245C374.803 2.56958 374.734 2.561 374.661 2.55242C374.589 2.54384 374.52 2.52668 374.447 2.52239C374.327 2.50952 374.203 2.50523 374.082 2.50523C374.061 2.50523 374.04 2.50523 374.018 2.50523C373.992 2.50523 373.971 2.50523 373.945 2.50523C373.825 2.50523 373.705 2.50952 373.589 2.52239C373.512 2.53097 373.439 2.54384 373.366 2.55671C373.302 2.56529 373.233 2.57387 373.169 2.58674C373.087 2.6039 373.01 2.62535 372.929 2.6468C372.868 2.65967 372.808 2.67254 372.753 2.69399C372.675 2.71543 372.598 2.74546 372.525 2.77549C372.465 2.79694 372.41 2.8141 372.349 2.83984C372.277 2.86987 372.208 2.90418 372.139 2.9385C372.079 2.96853 372.019 2.99427 371.963 3.0243C371.895 3.06291 371.83 3.10151 371.762 3.14441C371.706 3.17873 371.65 3.20876 371.595 3.24737C371.517 3.29885 371.449 3.35461 371.376 3.40609C371.333 3.43612 371.29 3.46615 371.251 3.50046C371.136 3.59484 371.028 3.69351 370.925 3.79646L351.468 23.2549L332.007 3.79217C330.296 2.08055 327.525 2.08055 325.813 3.79217C324.102 5.50379 324.102 8.275 325.813 9.98662L348.371 32.5466C350.083 34.2582 352.854 34.2582 354.565 32.5466L369.647 17.4637V50.834C369.647 53.2534 371.607 55.2138 374.027 55.2138C376.446 55.2138 378.406 53.2534 378.406 50.834V6.88511C378.406 6.73925 378.398 6.5934 378.385 6.44755ZM30.4894 29.252L49.6889 5.45232H39.3428L25.2005 22.9032L11.0625 5.45232H0.716337L19.9159 29.252L19.9845 29.3421L0 53.9998H11.0282L25.2048 35.8883L39.3814 53.9998H50.4095L30.425 29.3421L30.4937 29.252H30.4894ZM59.0313 0C55.6984 0 53.528 2.46234 53.528 5.44803C53.528 8.43372 55.6984 10.8961 59.0313 10.8961C62.3642 10.8961 64.5347 8.43372 64.5347 5.44803C64.5347 2.46234 62.3642 0 59.0313 0ZM54.6518 53.9998H63.4109V15.4647H54.6518V53.9998ZM103.487 30.7277V53.9955H94.7281V50.1476C92.193 53.1333 88.3025 54.9479 82.293 54.9479C79.5349 54.9479 70.2482 53.3692 69.2231 44.0561C68.2408 35.1591 75.5886 29.1877 89.3448 29.1877H94.7281C94.7281 24.4604 92.5448 21.5476 86.6553 21.4361C81.8598 21.346 77.832 23.2463 74.868 25.8202L71.4192 19.2182C75.8974 15.3446 83.0136 13.0624 90.4601 13.9804C102.646 15.4818 103.487 25.55 103.487 30.7277ZM94.7281 36.3817H90.4472C81.2035 36.3817 77.729 39.3416 78.055 42.7134C78.3724 46.0122 81.3622 47.445 85.0254 47.445C91.2794 47.445 94.7281 41.3235 94.7281 37.4541V36.3774V36.3817ZM147.54 34.5885C147.54 45.875 139.819 55.1752 127.976 55.1752C116.132 55.1752 108.411 45.8793 108.411 34.5885C108.411 23.2978 116.132 14.0019 127.976 14.0019C139.819 14.0019 147.54 23.2978 147.54 34.5885ZM138.781 34.5885C138.781 26.5495 134.024 21.835 127.971 21.835C121.919 21.835 117.162 26.5495 117.162 34.5885C117.162 42.6276 121.919 47.3421 127.971 47.3421C134.024 47.3421 138.781 42.6276 138.781 34.5885ZM214.386 53.9998H223.145V15.4647H214.386V53.9998ZM218.766 0C215.433 0 213.263 2.46234 213.263 5.44803C213.263 8.43372 215.433 10.8961 218.766 10.8961C222.099 10.8961 224.269 8.43372 224.269 5.44803C224.269 2.46234 222.099 0 218.766 0ZM193.973 13.7788C188.512 13.7788 184.528 16.0352 182.357 20.8055C180.307 15.7135 176.009 13.7788 171.869 13.7788C168.112 13.7788 163.166 15.469 161.498 19.969V15.469H152.919V54.0041H161.678V31.0323C161.678 28.201 162.6 21.8522 168.635 21.8522C174.67 21.8522 175.683 28.201 175.683 31.0323V54.0041H184.442V31.0323C184.442 28.201 185.364 21.8522 191.489 21.8522C197.615 21.8522 198.447 28.201 198.447 31.0323V54.0041H207.206V28.9646C207.206 18.9265 201.205 13.7831 193.982 13.7831L193.973 13.7788ZM419.855 45.4202C412.958 48.7362 404.439 47.4407 398.863 41.8597C393.286 36.283 391.987 27.7635 395.302 20.8655C396.203 18.9952 395.615 16.743 393.951 15.499C391.721 13.8303 388.534 14.6367 387.337 17.1506C382.503 27.3302 384.433 39.8607 392.647 48.0756C400.861 56.2906 413.391 58.221 423.57 53.3864C426.083 52.1938 426.885 49.0022 425.221 46.7715C423.977 45.1071 421.725 44.5194 419.855 45.4202ZM431.076 9.64344C422.862 1.4285 410.333 -0.501905 400.154 4.33268C397.64 5.52524 396.838 8.71684 398.502 10.9475C399.746 12.612 401.998 13.1997 403.868 12.2988C410.766 8.98281 419.285 10.2783 424.861 15.8593C430.437 21.4361 431.737 29.9556 428.421 36.8535C427.52 38.7239 428.108 40.976 429.772 42.2201C432.003 43.8888 435.19 43.0823 436.387 40.5685C441.221 30.3888 439.291 17.8541 431.076 9.64344Z" fill="url(#paint0_linear_1_3217)"/>
3
+ <defs>
4
+ <linearGradient id="paint0_linear_1_3217" x1="438.916" y1="28" x2="4.5156e-08" y2="28" gradientUnits="userSpaceOnUse">
5
+ <stop offset="0.158366" stop-color="#3D3834"/>
6
+ <stop offset="1" stop-color="#736B68"/>
7
+ </linearGradient>
8
+ </defs>
9
+ </svg>
@@ -10,9 +10,10 @@ import { useViewportLayout } from "@/app/hooks/use-viewport-layout";
10
10
  import { DesktopAppShell, getDesktopHostPlatform } from "@/platforms/desktop";
11
11
  import { MobileAppShell } from "@/platforms/mobile";
12
12
  import { PANEL_APPS_DOC_BROWSER_RENDERERS } from "@/features/panel-apps";
13
- import { SideDock, type SideDockManager } from "@/features/side-dock";
13
+ import { SideDock, type SideDockManager, useSideDockStore } from "@/features/side-dock";
14
14
  import { getPresenter } from "@/app/presenters/app.presenter";
15
15
  import { resolveUiDocumentTitle } from "@/shared/lib/ui-document-title";
16
+ import type { DocBrowserDockControls } from "@/shared/components/doc-browser/doc-browser-context";
16
17
 
17
18
  interface AppLayoutProps {
18
19
  children: React.ReactNode;
@@ -28,6 +29,12 @@ function AppLayoutInner({
28
29
  const { language } = useI18n();
29
30
  const { isMobile } = useViewportLayout();
30
31
  const desktopHostPlatform = getDesktopHostPlatform();
32
+ useSideDockStore((state) => state.pinnedItems);
33
+ const docBrowserDockControls: DocBrowserDockControls = {
34
+ getDockState: sideDockManager.getDockState,
35
+ pinTab: sideDockManager.pinTab,
36
+ unpinTab: sideDockManager.unpinTab,
37
+ };
31
38
 
32
39
  useEffect(() => {
33
40
  document.title = resolveUiDocumentTitle(pathname);
@@ -35,7 +42,7 @@ function AppLayoutInner({
35
42
 
36
43
  if (isMobile && desktopHostPlatform !== "win32") {
37
44
  return (
38
- <MobileAppShell pathname={pathname} isDocBrowserOpen={isOpen} docBrowserRenderers={PANEL_APPS_DOC_BROWSER_RENDERERS} topbarLeadingInset={desktopHostPlatform === "darwin" ? "4.75rem" : undefined}>
45
+ <MobileAppShell pathname={pathname} isDocBrowserOpen={isOpen} docBrowserDockControls={docBrowserDockControls} docBrowserRenderers={PANEL_APPS_DOC_BROWSER_RENDERERS} topbarLeadingInset={desktopHostPlatform === "darwin" ? "4.75rem" : undefined}>
39
46
  {children}
40
47
  </MobileAppShell>
41
48
  );
@@ -47,6 +54,7 @@ function AppLayoutInner({
47
54
  isMobileLayout={isMobile}
48
55
  isDocBrowserOpen={isOpen}
49
56
  docBrowserMode={mode}
57
+ docBrowserDockControls={docBrowserDockControls}
50
58
  docBrowserRenderers={PANEL_APPS_DOC_BROWSER_RENDERERS}
51
59
  sideDock={<SideDock manager={sideDockManager} />}
52
60
  >
@@ -4,7 +4,7 @@ import {
4
4
  useAgents,
5
5
  useUpdateAgent,
6
6
  } from "@/shared/hooks/use-agents";
7
- import { useConfig, useConfigMeta } from "@/shared/hooks/use-config";
7
+ import { useConfig, useProviderTemplates, useProviders } from "@/shared/hooks/use-config";
8
8
  import type { AgentProfileView } from "@/shared/lib/api";
9
9
  import {
10
10
  AgentEditDialog,
@@ -237,7 +237,8 @@ export function AgentsPage() {
237
237
  const presenter = usePresenter();
238
238
  const agentsQuery = useAgents();
239
239
  const configQuery = useConfig();
240
- const configMetaQuery = useConfigMeta();
240
+ const providersQuery = useProviders();
241
+ const templatesQuery = useProviderTemplates();
241
242
  const sessionTypesQuery = useNcpChatSessionTypes();
242
243
  const updateAgent = useUpdateAgent();
243
244
  const deleteAgent = useDeleteAgent();
@@ -261,10 +262,11 @@ export function AgentsPage() {
261
262
  () =>
262
263
  buildProviderModelCatalog({
263
264
  config: configQuery.data,
264
- meta: configMetaQuery.data,
265
+ providersView: providersQuery.data,
266
+ templatesView: templatesQuery.data,
265
267
  onlyConfigured: true,
266
268
  }),
267
- [configMetaQuery.data, configQuery.data],
269
+ [configQuery.data, providersQuery.data, templatesQuery.data],
268
270
  );
269
271
  const runtimeOptions = useMemo(
270
272
  () => buildSessionTypeOptions(sessionTypesQuery.data?.options ?? []),
@@ -12,9 +12,10 @@ import {
12
12
  } from '@/features/chat/utils/chat-session-preference-governance.utils';
13
13
  import {
14
14
  useConfig,
15
- useConfigMeta,
16
15
  useNcpSessionSkills,
17
- useNcpSessions
16
+ useNcpSessions,
17
+ useProviders,
18
+ useProviderTemplates
18
19
  } from '@/shared/hooks/use-config';
19
20
  import { useNcpChatSessionTypes } from './use-ncp-chat-session-types';
20
21
  import { buildProviderModelCatalog, composeProviderModel, resolveModelThinkingCapability } from '@/shared/lib/provider-models';
@@ -38,12 +39,14 @@ function filterSessionsByQuery(sessions: SessionEntryView[], query: string): Ses
38
39
 
39
40
  function useNcpChatModelOptions(params: {
40
41
  config: ReturnType<typeof useConfig>['data'];
41
- meta: ReturnType<typeof useConfigMeta>['data'];
42
+ providersView: ReturnType<typeof useProviders>['data'];
43
+ templatesView: ReturnType<typeof useProviderTemplates>['data'];
42
44
  }) {
43
- const { config, meta } = params;
45
+ const { config, providersView, templatesView } = params;
44
46
  return useMemo<ChatModelOption[]>(() => {
45
47
  const providers = buildProviderModelCatalog({
46
- meta,
48
+ providersView,
49
+ templatesView,
47
50
  config,
48
51
  onlyConfigured: true
49
52
  });
@@ -71,7 +74,7 @@ function useNcpChatModelOptions(params: {
71
74
  }
72
75
  return left.modelLabel.localeCompare(right.modelLabel);
73
76
  });
74
- }, [config, meta]);
77
+ }, [config, providersView, templatesView]);
75
78
  }
76
79
 
77
80
  function useRecentSessionPreferences(params: {
@@ -154,7 +157,8 @@ export function useNcpChatPageData(params: UseNcpChatPageDataParams) {
154
157
  setSelectedThinkingLevel,
155
158
  } = params;
156
159
  const configQuery = useConfig();
157
- const configMetaQuery = useConfigMeta();
160
+ const providersQuery = useProviders();
161
+ const templatesQuery = useProviderTemplates();
158
162
  const sessionsQuery = useNcpSessions({ limit: 200 });
159
163
  const sessionTypesQuery = useNcpChatSessionTypes();
160
164
  const sessionSkillsQuery = useNcpSessionSkills({
@@ -165,10 +169,12 @@ export function useNcpChatPageData(params: UseNcpChatPageDataParams) {
165
169
  });
166
170
  const isProviderStateResolved =
167
171
  (configQuery.isFetched || configQuery.isSuccess) &&
168
- (configMetaQuery.isFetched || configMetaQuery.isSuccess);
172
+ (providersQuery.isFetched || providersQuery.isSuccess) &&
173
+ (templatesQuery.isFetched || templatesQuery.isSuccess);
169
174
  const modelOptions = useNcpChatModelOptions({
170
175
  config: configQuery.data,
171
- meta: configMetaQuery.data
176
+ providersView: providersQuery.data,
177
+ templatesView: templatesQuery.data
172
178
  });
173
179
 
174
180
  const sessionSummaries = useMemo(
@@ -238,7 +244,8 @@ export function useNcpChatPageData(params: UseNcpChatPageDataParams) {
238
244
 
239
245
  return {
240
246
  configQuery,
241
- configMetaQuery,
247
+ providersQuery,
248
+ templatesQuery,
242
249
  sessionsQuery,
243
250
  sessionTypesQuery,
244
251
  sessionSkillsQuery,
@@ -19,6 +19,7 @@ import { cn } from "@/shared/lib/utils";
19
19
  import {
20
20
  CheckCircle2,
21
21
  Download,
22
+ RefreshCw,
22
23
  Trash2,
23
24
  } from "lucide-react";
24
25
 
@@ -35,6 +36,7 @@ type MarketplaceListCardActionProps = {
35
36
  record?: MarketplaceInstalledRecord;
36
37
  isInstalling: boolean;
37
38
  isDisabled: boolean;
39
+ canUpdate: boolean;
38
40
  canUninstall: boolean;
39
41
  busyAction?: MarketplaceManageAction;
40
42
  busyForRecord: boolean;
@@ -96,6 +98,7 @@ function MarketplaceListCardActions(props: MarketplaceListCardActionProps) {
96
98
  record,
97
99
  isInstalling,
98
100
  isDisabled,
101
+ canUpdate,
99
102
  canUninstall,
100
103
  busyAction,
101
104
  busyForRecord,
@@ -103,7 +106,7 @@ function MarketplaceListCardActions(props: MarketplaceListCardActionProps) {
103
106
  onInstall,
104
107
  onManage,
105
108
  } = props;
106
- const hasActions = Boolean((item && !record) || (record && canUninstall));
109
+ const hasActions = Boolean((item && !record) || (record && (canUpdate || canUninstall)));
107
110
 
108
111
  return (
109
112
  <div
@@ -148,6 +151,22 @@ function MarketplaceListCardActions(props: MarketplaceListCardActionProps) {
148
151
  </button>
149
152
  )}
150
153
 
154
+ {record && canUpdate && (
155
+ <button
156
+ disabled={busyForRecord}
157
+ onClick={(event) => {
158
+ event.stopPropagation();
159
+ onManage("update", record);
160
+ }}
161
+ className="inline-flex h-8 items-center gap-1.5 whitespace-nowrap rounded-xl border border-blue-200/80 bg-white px-3 text-xs font-medium text-blue-600 transition-colors hover:border-blue-300 hover:bg-blue-50 disabled:opacity-50"
162
+ >
163
+ <RefreshCw className="h-3.5 w-3.5" />
164
+ {busyAction === "update"
165
+ ? t("marketplaceUpdating")
166
+ : t("marketplaceUpdate")}
167
+ </button>
168
+ )}
169
+
151
170
  {record && canUninstall && (
152
171
  <button
153
172
  disabled={busyForRecord}
@@ -241,6 +260,7 @@ export function MarketplaceListCard(props: {
241
260
  : undefined;
242
261
  const busyForRecord = Boolean(busyAction);
243
262
  const canUninstall = record?.type === "skill" && record.source === "workspace";
263
+ const canUpdate = record?.type === "skill" && record.origin === "marketplace";
244
264
  const isDisabled = record
245
265
  ? record.enabled === false || record.runtimeStatus === "disabled"
246
266
  : false;
@@ -269,6 +289,7 @@ export function MarketplaceListCard(props: {
269
289
  record={record}
270
290
  isInstalling={isInstalling}
271
291
  isDisabled={isDisabled}
292
+ canUpdate={canUpdate}
272
293
  canUninstall={canUninstall}
273
294
  busyAction={busyAction}
274
295
  busyForRecord={busyForRecord}
@@ -282,7 +282,9 @@ export function MarketplacePage(props: MarketplacePageProps = {}) {
282
282
  action: MarketplaceManageAction,
283
283
  record: MarketplaceInstalledRecord,
284
284
  ) => {
285
- const targetId = record.id || record.spec;
285
+ const targetId = action === "update"
286
+ ? record.catalogSlug || record.id || record.spec
287
+ : record.id || record.spec;
286
288
  if (!targetId) {
287
289
  return;
288
290
  }
@@ -178,7 +178,9 @@ export function useManageMarketplaceItem() {
178
178
  ? t('marketplaceEnableSuccess')
179
179
  : result.action === 'disable'
180
180
  ? t('marketplaceDisableSuccess')
181
- : t('marketplaceUninstallSuccess');
181
+ : result.action === 'update'
182
+ ? t('marketplaceUpdateSuccess')
183
+ : t('marketplaceUninstallSuccess');
182
184
  toast.success(result.message || fallback);
183
185
  },
184
186
  onError: (error: Error) => {
@@ -133,6 +133,14 @@ export function applyManageResultToInstalledView(params: {
133
133
  };
134
134
  }
135
135
 
136
+ if (params.result.action === 'update') {
137
+ return {
138
+ ...record,
139
+ installedAt: new Date().toISOString(),
140
+ origin: record.origin ?? 'marketplace'
141
+ };
142
+ }
143
+
136
144
  return {
137
145
  ...record,
138
146
  enabled: true,
@@ -1,5 +1,5 @@
1
1
  import { t } from '@/shared/lib/i18n';
2
- import type { ParsedResourceUri, ResourceUriRouteDefinition } from '@/shared/lib/resource-uri';
2
+ import { parseResourceUri, type ParsedResourceUri, type ResourceUriRouteDefinition } from '@/shared/lib/resource-uri';
3
3
  import {
4
4
  getDefaultDocsUrl,
5
5
  inferTabTitle,
@@ -32,9 +32,67 @@ function resolveNextclawDocsUrl(uri: ParsedResourceUri): string {
32
32
  return normalizeUrlByKind(rawPath, 'docs');
33
33
  }
34
34
 
35
+ function createDocsResourceUriFromSegments(pathSegments: string[]): string {
36
+ const path = pathSegments
37
+ .filter((segment) => segment.trim().length > 0)
38
+ .map((segment) => encodeURIComponent(decodeURIComponent(segment)))
39
+ .join('/');
40
+ return path ? `nextclaw://docs/${path}` : 'nextclaw://docs';
41
+ }
42
+
43
+ function createDocsResourceUriFromUrl(url: string): string {
44
+ const normalized = normalizeDocUrl(url);
45
+ const pathname = normalized.startsWith('/')
46
+ ? normalized
47
+ : (() => {
48
+ try {
49
+ return new URL(url).pathname;
50
+ } catch {
51
+ return '';
52
+ }
53
+ })();
54
+ if (!pathname) {
55
+ return 'nextclaw://docs';
56
+ }
57
+ return createDocsResourceUriFromSegments(pathname.split('/'));
58
+ }
59
+
60
+ function getPanelAppId(uri: ParsedResourceUri): string {
61
+ if (uri.scheme === 'nextclaw' && uri.authority === 'panel-app') {
62
+ return uri.pathSegments[0] ?? '';
63
+ }
64
+ const [apiSegment, collectionSegment, appId, contentSegment] = uri.pathSegments;
65
+ return apiSegment === 'api'
66
+ && collectionSegment === 'panel-apps'
67
+ && appId !== undefined
68
+ && appId.length > 0
69
+ && contentSegment === 'content'
70
+ ? appId
71
+ : '';
72
+ }
73
+
74
+ function isPanelAppContentUri(uri: ParsedResourceUri): boolean {
75
+ return getPanelAppId(uri).length > 0;
76
+ }
77
+
35
78
  function resolvePanelAppPlaceholderUrl(uri: ParsedResourceUri): string {
36
- const appId = uri.pathSegments[0] ?? '';
37
- return appId ? `nextclaw://panel-app/${encodeURIComponent(appId)}` : 'nextclaw://panel-app';
79
+ const appId = getPanelAppId(uri);
80
+ return appId ? `/api/panel-apps/${encodeURIComponent(decodeURIComponent(appId))}/content` : 'nextclaw://panel-app';
81
+ }
82
+
83
+ function createPanelAppResourceUri(uri: ParsedResourceUri): string {
84
+ const appId = getPanelAppId(uri);
85
+ return appId ? `nextclaw://panel-app/${encodeURIComponent(decodeURIComponent(appId))}` : 'nextclaw://panel-app';
86
+ }
87
+
88
+ function arePanelAppUrlsEquivalent(left: string, right: string): boolean {
89
+ const leftUri = parseResourceUri(left);
90
+ const rightUri = parseResourceUri(right);
91
+ const leftAppId = getPanelAppId(leftUri);
92
+ const rightAppId = getPanelAppId(rightUri);
93
+ return leftAppId.length > 0 && rightAppId.length > 0
94
+ ? decodeURIComponent(leftAppId) === decodeURIComponent(rightAppId)
95
+ : left === right;
38
96
  }
39
97
 
40
98
  export const RIGHT_PANEL_RESOURCE_ROUTE_DEFINITIONS: RightPanelResourceRouteDefinition[] = [
@@ -46,6 +104,7 @@ export const RIGHT_PANEL_RESOURCE_ROUTE_DEFINITIONS: RightPanelResourceRouteDefi
46
104
  resolve: () => ({
47
105
  historyPolicy: 'managed',
48
106
  kind: RIGHT_PANEL_HOME_TAB_KIND,
107
+ resourceUri: RIGHT_PANEL_HOME_URL,
49
108
  title: t('docBrowserHomeTitle'),
50
109
  url: RIGHT_PANEL_HOME_URL,
51
110
  }),
@@ -61,6 +120,7 @@ export const RIGHT_PANEL_RESOURCE_ROUTE_DEFINITIONS: RightPanelResourceRouteDefi
61
120
  return {
62
121
  historyPolicy: 'managed',
63
122
  kind: 'docs',
123
+ resourceUri: createDocsResourceUriFromUrl(url),
64
124
  title: t('docBrowserHelp'),
65
125
  url,
66
126
  };
@@ -77,6 +137,7 @@ export const RIGHT_PANEL_RESOURCE_ROUTE_DEFINITIONS: RightPanelResourceRouteDefi
77
137
  return {
78
138
  historyPolicy: 'managed',
79
139
  kind: 'docs',
140
+ resourceUri: createDocsResourceUriFromSegments(uri.pathSegments),
80
141
  title: t('docBrowserHelp'),
81
142
  url,
82
143
  };
@@ -94,6 +155,7 @@ export const RIGHT_PANEL_RESOURCE_ROUTE_DEFINITIONS: RightPanelResourceRouteDefi
94
155
  dedupeKey: 'apps',
95
156
  historyPolicy: 'managed',
96
157
  kind: RIGHT_PANEL_APPS_TAB_KIND,
158
+ resourceUri: url,
97
159
  title: url === RIGHT_PANEL_APPS_URL ? t('appsTitle') : t('serviceAppsTitle'),
98
160
  url,
99
161
  };
@@ -104,19 +166,20 @@ export const RIGHT_PANEL_RESOURCE_ROUTE_DEFINITIONS: RightPanelResourceRouteDefi
104
166
  defaultUrl: () => 'nextclaw://panel-app',
105
167
  id: 'panel-app',
106
168
  kind: RIGHT_PANEL_PANEL_APP_TAB_KIND,
107
- match: (uri) => uri.scheme === 'nextclaw' && uri.authority === 'panel-app',
169
+ match: (uri) => (uri.scheme === 'nextclaw' && uri.authority === 'panel-app') || isPanelAppContentUri(uri),
108
170
  resolve: (uri) => {
109
171
  const url = resolvePanelAppPlaceholderUrl(uri);
110
- const appId = uri.pathSegments[0] ?? '';
172
+ const appId = getPanelAppId(uri);
111
173
  return {
112
174
  dedupeKey: appId ? `panel-app:${decodeURIComponent(appId)}` : undefined,
113
175
  historyPolicy: 'managed',
114
176
  kind: RIGHT_PANEL_PANEL_APP_TAB_KIND,
177
+ resourceUri: createPanelAppResourceUri(uri),
115
178
  title: t('panelAppsTitle'),
116
179
  url,
117
180
  };
118
181
  },
119
- areEquivalent: (left, right) => left === right,
182
+ areEquivalent: arePanelAppUrlsEquivalent,
120
183
  },
121
184
  {
122
185
  defaultUrl: () => 'about:blank',
@@ -126,6 +189,7 @@ export const RIGHT_PANEL_RESOURCE_ROUTE_DEFINITIONS: RightPanelResourceRouteDefi
126
189
  resolve: (uri) => ({
127
190
  historyPolicy: 'managed',
128
191
  kind: 'content',
192
+ resourceUri: uri.raw || 'about:blank',
129
193
  title: inferTabTitle(uri.raw, 'content', 'Detail'),
130
194
  url: uri.raw || 'about:blank',
131
195
  }),
@@ -8,11 +8,13 @@ describe('RightPanelResourceRouteResolver', () => {
8
8
  expect(resolver.resolve('nextclaw://apps')).toMatchObject({
9
9
  dedupeKey: 'apps',
10
10
  kind: 'apps',
11
+ resourceUri: 'nextclaw://apps',
11
12
  url: 'nextclaw://apps',
12
13
  });
13
14
  expect(resolver.resolve('nextclaw://apps?tab=service-apps')).toMatchObject({
14
15
  dedupeKey: 'apps',
15
16
  kind: 'apps',
17
+ resourceUri: 'nextclaw://apps?tab=service-apps',
16
18
  url: 'nextclaw://apps?tab=service-apps',
17
19
  });
18
20
  });
@@ -22,6 +24,7 @@ describe('RightPanelResourceRouteResolver', () => {
22
24
  const target = resolver.resolve('nextclaw://docs/guide/getting-started');
23
25
 
24
26
  expect(target.kind).toBe('docs');
27
+ expect(target.resourceUri).toBe('nextclaw://docs/guide/getting-started');
25
28
  expect(target.title).toBe('Help Docs');
26
29
  expect(target.url).toContain('/guide/getting-started');
27
30
  });
@@ -32,7 +35,28 @@ describe('RightPanelResourceRouteResolver', () => {
32
35
  expect(resolver.resolve('nextclaw://panel-app/timer')).toMatchObject({
33
36
  dedupeKey: 'panel-app:timer',
34
37
  kind: 'panel-app',
35
- url: 'nextclaw://panel-app/timer',
38
+ resourceUri: 'nextclaw://panel-app/timer',
39
+ url: '/api/panel-apps/timer/content',
36
40
  });
37
41
  });
42
+
43
+ it('keeps panel app content URLs idempotent under panel app kind', () => {
44
+ const resolver = new RightPanelResourceRouteResolver();
45
+
46
+ expect(resolver.resolveOpenTarget({
47
+ kind: 'panel-app',
48
+ url: '/api/panel-apps/timer/content',
49
+ })).toMatchObject({
50
+ dedupeKey: 'panel-app:timer',
51
+ kind: 'panel-app',
52
+ resourceUri: 'nextclaw://panel-app/timer',
53
+ url: '/api/panel-apps/timer/content',
54
+ });
55
+ expect(resolver.areUrlsEquivalent(
56
+ 'nextclaw://panel-app/timer',
57
+ '/api/panel-apps/timer/content',
58
+ 'panel-app',
59
+ 'panel-app',
60
+ )).toBe(true);
61
+ });
38
62
  });
@@ -21,7 +21,7 @@ function inferFallbackKind(url?: string): DocBrowserTabKind {
21
21
  export class RightPanelResourceRouteResolver implements DocBrowserRouteResolver {
22
22
  private readonly resourceUriResolver = new ResourceUriResolver<RightPanelResourceTarget>(
23
23
  RIGHT_PANEL_RESOURCE_ROUTE_DEFINITIONS_FOR_RESOURCE_URI,
24
- { getNormalizedUri: (target) => target.url },
24
+ { getNormalizedUri: (target) => target.resourceUri ?? target.url },
25
25
  );
26
26
 
27
27
  resolve = (uri: string): RightPanelResourceTarget => this.resourceUriResolver.resolve(uri);
@@ -0,0 +1,42 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import type { PanelAppEntryView } from '@/shared/lib/api';
3
+ import { createPanelAppRightPanelResourceTarget } from '@/features/right-panel-resources/utils/right-panel-resource-uri.utils';
4
+
5
+ function createPanelAppEntry(overrides: Partial<PanelAppEntryView> = {}): PanelAppEntryView {
6
+ return {
7
+ contentPath: '/api/panel-apps/demo/content',
8
+ createdAt: '2026-06-02T00:00:00.000Z',
9
+ favorite: false,
10
+ fileName: 'demo.html',
11
+ id: 'demo',
12
+ openCount: 0,
13
+ sizeBytes: 1024,
14
+ title: 'Demo App',
15
+ updatedAt: '2026-06-02T00:00:00.000Z',
16
+ ...overrides,
17
+ };
18
+ }
19
+
20
+ describe('right-panel-resource uri utils', () => {
21
+ it('keeps panel app image icons as dock image icons', () => {
22
+ const target = createPanelAppRightPanelResourceTarget(createPanelAppEntry({
23
+ icon: '/api/panel-apps/demo/assets/icon.png',
24
+ }));
25
+
26
+ expect(target.dockIcon).toEqual({
27
+ type: 'url',
28
+ url: '/api/panel-apps/demo/assets/icon.png',
29
+ });
30
+ });
31
+
32
+ it('keeps panel app text icons as dock text icons', () => {
33
+ const target = createPanelAppRightPanelResourceTarget(createPanelAppEntry({
34
+ icon: '🧭',
35
+ }));
36
+
37
+ expect(target.dockIcon).toEqual({
38
+ type: 'text',
39
+ value: '🧭',
40
+ });
41
+ });
42
+ });