@nextclaw/ui 0.12.4 → 0.12.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 (115) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/dist/assets/{ChannelsList-CobWeI2V.js → ChannelsList-C6-lh55g.js} +2 -2
  3. package/dist/assets/ChatPage-DOW0gPc2.js +45 -0
  4. package/dist/assets/DocBrowser-CGyeswYP.js +1 -0
  5. package/dist/assets/{DocBrowser-NSzgVKka.js → DocBrowser-QUZ3nfmH.js} +1 -1
  6. package/dist/assets/{DocBrowserContext-DpgVdRgk.js → DocBrowserContext-CpiIfhJO.js} +1 -1
  7. package/dist/assets/{LogoBadge-CHS4YNLw.js → LogoBadge-BUK13xK5.js} +1 -1
  8. package/dist/assets/MarketplacePage-BDVwhIYE.js +1 -0
  9. package/dist/assets/MarketplacePage-LnKKL3xK.js +49 -0
  10. package/dist/assets/McpMarketplacePage-BG4T_Pcx.js +40 -0
  11. package/dist/assets/ModelConfig-LtWuogIw.js +1 -0
  12. package/dist/assets/ProviderScopedModelInput-DGn6sFEN.js +1 -0
  13. package/dist/assets/ProvidersList-ma-_MlLo.js +1 -0
  14. package/dist/assets/{RemoteAccessPage-yfbrveNQ.js → RemoteAccessPage-ff15qO-c.js} +1 -1
  15. package/dist/assets/RuntimeConfig-TgPandXF.js +1 -0
  16. package/dist/assets/SearchConfig-C9iBt7pl.js +1 -0
  17. package/dist/assets/{SecretsConfig-CLFSSoTl.js → SecretsConfig-Bew4EF2A.js} +2 -2
  18. package/dist/assets/{SessionsConfig-vYrvc2Fk.js → SessionsConfig-2r2yAGZg.js} +2 -2
  19. package/dist/assets/{book-open-C7TAghTk.js → book-open-CJG8Yz3U.js} +1 -1
  20. package/dist/assets/{chat-session-display-5dVFkJyw.js → chat-session-display-DkAC5OMC.js} +1 -1
  21. package/dist/assets/{chunk-JZWAC4HX-DbL4EmiT.js → chunk-JZWAC4HX-D5b3Iyas.js} +1 -1
  22. package/dist/assets/{config-CMiW0yaK.js → config-zvnxSXSP.js} +1 -1
  23. package/dist/assets/{createLucideIcon-BRLFtf-8.js → createLucideIcon-_FMJqZw2.js} +1 -1
  24. package/dist/assets/{dist-DP-JKR4G.js → dist-B1fpOuON.js} +1 -1
  25. package/dist/assets/{dist-BFc_H-lY.js → dist-BCXX7FD-.js} +2 -2
  26. package/dist/assets/{external-link-BkJkiWbH.js → external-link-b7gAJWYY.js} +1 -1
  27. package/dist/assets/{hash-CbP6-6R9.js → hash-Bhy4TwfZ.js} +1 -1
  28. package/dist/assets/{i18n-C_2dKw6w.js → i18n-DJg9BPYk.js} +1 -1
  29. package/dist/assets/index-BoJbxdvZ.css +1 -0
  30. package/dist/assets/index-CtlT4E9Y.js +6 -0
  31. package/dist/assets/infiniteQueryBehavior-CTcVlD9s.js +1 -0
  32. package/dist/assets/loader-circle-B60I0hEk.js +1 -0
  33. package/dist/assets/{logos-N3dbS6-I.js → logos-GMeYU9vc.js} +1 -1
  34. package/dist/assets/{page-layout-DyuvlNrg.js → page-layout-C8UbWuMt.js} +1 -1
  35. package/dist/assets/plus-CR7RfK3H.js +1 -0
  36. package/dist/assets/{popover-BKKWGUaG.js → popover-8HSx9wQj.js} +1 -1
  37. package/dist/assets/react-BB4jko2M.js +1 -0
  38. package/dist/assets/{refresh-ccw-BGMdiNGq.js → refresh-ccw-CA4_C7Zg.js} +1 -1
  39. package/dist/assets/{save-Dh4GQzzX.js → save-BtvMy4lk.js} +1 -1
  40. package/dist/assets/search-C60UA27E.js +1 -0
  41. package/dist/assets/security-config-BkFDYZ6j.js +1 -0
  42. package/dist/assets/{select-BtIi5fnh.js → select-xp_Ac8ip.js} +1 -1
  43. package/dist/assets/skeleton-uxz_5h3A.js +1 -0
  44. package/dist/assets/{status-dot-C4O-2jZP.js → status-dot-Cn4Pp7DZ.js} +1 -1
  45. package/dist/assets/{switch-DPegGIa_.js → switch-BTi6UOij.js} +1 -1
  46. package/dist/assets/{tabs-custom-x5GZexrF.js → tabs-custom-BiiN8DME.js} +1 -1
  47. package/dist/assets/{trash-2-CU3LYIpQ.js → trash-2-BpsF0N-r.js} +1 -1
  48. package/dist/assets/use-infinite-scroll-loader-C8jBv11-.js +1 -0
  49. package/dist/assets/{useConfirmDialog-S5WsGOGf.js → useConfirmDialog-BJIwUZjH.js} +1 -1
  50. package/dist/assets/{useMutation-DSinpgEq.js → useMutation-BjBOKHj_.js} +1 -1
  51. package/dist/assets/x-BfTu-g7D.js +1 -0
  52. package/dist/index.html +19 -18
  53. package/package.json +4 -4
  54. package/src/account/components/account-panel.tsx +46 -4
  55. package/src/account/managers/account.manager.ts +19 -4
  56. package/src/api/remote.ts +9 -0
  57. package/src/api/remote.types.ts +5 -0
  58. package/src/components/chat/ChatConversationPanel.test.tsx +183 -141
  59. package/src/components/chat/adapters/chat-message-tool-agent-id.test.ts +11 -11
  60. package/src/components/chat/adapters/chat-message.adapter.test.ts +43 -6
  61. package/src/components/chat/adapters/chat-message.session-request-tool-card.ts +182 -44
  62. package/src/components/chat/adapters/chat-message.session-spawn-tool-card.test.ts +104 -0
  63. package/src/components/chat/chat-child-session-panel.tsx +103 -45
  64. package/src/components/chat/chat-page-runtime.test.ts +16 -19
  65. package/src/components/chat/chat-session-preference-sync.test.ts +13 -0
  66. package/src/components/chat/chat-session-preference-sync.ts +9 -7
  67. package/src/components/chat/hooks/use-chat-session-project.test.tsx +5 -5
  68. package/src/components/chat/hooks/use-chat-session-project.ts +0 -5
  69. package/src/components/chat/hooks/use-chat-session-update.test.tsx +75 -0
  70. package/src/components/chat/hooks/use-chat-session-update.ts +4 -2
  71. package/src/components/chat/managers/chat-session-list.manager.test.ts +45 -5
  72. package/src/components/chat/managers/chat-session-list.manager.ts +18 -4
  73. package/src/components/chat/ncp/NcpChatPage.tsx +32 -51
  74. package/src/components/chat/ncp/ncp-chat-input.manager.ts +3 -5
  75. package/src/components/chat/ncp/ncp-chat-page-data.ts +0 -1
  76. package/src/components/chat/ncp/ncp-chat.presenter.ts +1 -11
  77. package/src/components/chat/ncp/session-conversation/use-ncp-child-session-tabs-view.ts +20 -7
  78. package/src/components/chat/stores/chat-session-list.store.ts +3 -0
  79. package/src/components/chat/useChatSessionTypeState.test.tsx +0 -3
  80. package/src/components/chat/useChatSessionTypeState.ts +3 -5
  81. package/src/components/config/ChannelsList.test.tsx +68 -0
  82. package/src/components/config/ChannelsList.tsx +22 -4
  83. package/src/components/config/ProvidersList.tsx +17 -3
  84. package/src/components/config/providers-list.test.tsx +68 -0
  85. package/src/components/layout/Sidebar.tsx +13 -13
  86. package/src/components/layout/sidebar.layout.test.tsx +32 -1
  87. package/src/components/marketplace/MarketplacePage.tsx +30 -30
  88. package/src/components/marketplace/marketplace-page-parts.tsx +16 -24
  89. package/src/components/marketplace/mcp/McpMarketplacePage.tsx +28 -26
  90. package/src/hooks/marketplace-list-pages.ts +27 -0
  91. package/src/hooks/use-infinite-scroll-loader.ts +88 -0
  92. package/src/hooks/useMarketplace.ts +14 -3
  93. package/src/hooks/useMcpMarketplace.ts +14 -3
  94. package/src/lib/i18n.remote.ts +15 -0
  95. package/dist/assets/ChatPage-ZIdFFVAv.js +0 -43
  96. package/dist/assets/DocBrowser-D55C0iyl.js +0 -1
  97. package/dist/assets/MarketplacePage-BFYsRss_.js +0 -49
  98. package/dist/assets/MarketplacePage-DII-q-Y1.js +0 -1
  99. package/dist/assets/McpMarketplacePage-CPqsGJzz.js +0 -40
  100. package/dist/assets/ModelConfig-Bvuo_IpS.js +0 -1
  101. package/dist/assets/ProviderScopedModelInput-BfY8rGsf.js +0 -1
  102. package/dist/assets/ProvidersList-3tlaqwSS.js +0 -1
  103. package/dist/assets/RuntimeConfig-CAd5Kta3.js +0 -1
  104. package/dist/assets/SearchConfig-DFwgaAa7.js +0 -1
  105. package/dist/assets/index-ChUXhq0G.css +0 -1
  106. package/dist/assets/index-DAE8Srx-.js +0 -6
  107. package/dist/assets/label-D8yyejJS.js +0 -1
  108. package/dist/assets/loader-circle-B0sKKO29.js +0 -1
  109. package/dist/assets/marketplace-localization-CxSTG9wr.js +0 -1
  110. package/dist/assets/plus-CYXs3JtZ.js +0 -1
  111. package/dist/assets/react-8EIEQjMP.js +0 -1
  112. package/dist/assets/search-DOsLw-P9.js +0 -1
  113. package/dist/assets/security-config-CM_tQRXQ.js +0 -1
  114. package/dist/assets/skeleton-GbHLjPC0.js +0 -1
  115. package/dist/assets/x-Bnco_K8b.js +0 -1
@@ -1 +1 @@
1
- import{_ as e,i as t,m as n,p as r}from"./i18n-C_2dKw6w.js";import{o as i}from"./dist-BFc_H-lY.js";import{at as a,et as o,it as s,nt as c,rt as l,tt as u}from"./index-DAE8Srx-.js";var d=e(n(),1),f=r(),p=({open:e,onOpenChange:n,title:r,description:d,confirmLabel:p=t(`confirm`),cancelLabel:m=t(`cancel`),variant:h=`default`,onConfirm:g,onCancel:_})=>(0,f.jsx)(o,{open:e,onOpenChange:n,children:(0,f.jsxs)(u,{className:`[&>:last-child]:hidden`,onCloseAutoFocus:e=>e.preventDefault(),children:[(0,f.jsxs)(s,{children:[(0,f.jsx)(a,{children:r}),d?(0,f.jsx)(c,{children:d}):null]}),(0,f.jsxs)(l,{className:`gap-2 sm:gap-0`,children:[(0,f.jsx)(i,{type:`button`,variant:`outline`,onClick:()=>{_(),n(!1)},children:m}),(0,f.jsx)(i,{type:`button`,variant:h===`destructive`?`destructive`:`default`,onClick:()=>{g(),n(!1)},children:p})]})]})}),m={open:!1,title:``,description:``,confirmLabel:t(`confirm`),cancelLabel:t(`cancel`),variant:`default`,resolve:null};function h(){let[e,n]=(0,d.useState)(m),r=(0,d.useCallback)(e=>new Promise(r=>{n({open:!0,title:e.title,description:e.description??``,confirmLabel:e.confirmLabel??t(`confirm`),cancelLabel:e.cancelLabel??t(`cancel`),variant:e.variant??`default`,resolve:e=>{r(e),n(e=>({...e,open:!1,resolve:null}))}})}),[]),i=(0,d.useCallback)(e=>{n(t=>(!e&&t.resolve&&t.resolve(!1),{...t,open:e,resolve:e?t.resolve:null}))},[]);return{confirm:r,ConfirmDialog:(0,d.useCallback)(()=>(0,f.jsx)(p,{open:e.open,onOpenChange:i,title:e.title,description:e.description||void 0,confirmLabel:e.confirmLabel,cancelLabel:e.cancelLabel,variant:e.variant,onConfirm:()=>e.resolve?.(!0),onCancel:()=>e.resolve?.(!1)}),[e,i])}}export{h as t};
1
+ import{_ as e,i as t,m as n,p as r}from"./i18n-DJg9BPYk.js";import{o as i}from"./dist-BCXX7FD-.js";import{at as a,it as o,nt as s,ot as c,rt as l,tt as u}from"./index-CtlT4E9Y.js";var d=e(n(),1),f=r(),p=({open:e,onOpenChange:n,title:r,description:d,confirmLabel:p=t(`confirm`),cancelLabel:m=t(`cancel`),variant:h=`default`,onConfirm:g,onCancel:_})=>(0,f.jsx)(u,{open:e,onOpenChange:n,children:(0,f.jsxs)(s,{className:`[&>:last-child]:hidden`,onCloseAutoFocus:e=>e.preventDefault(),children:[(0,f.jsxs)(a,{children:[(0,f.jsx)(c,{children:r}),d?(0,f.jsx)(l,{children:d}):null]}),(0,f.jsxs)(o,{className:`gap-2 sm:gap-0`,children:[(0,f.jsx)(i,{type:`button`,variant:`outline`,onClick:()=>{_(),n(!1)},children:m}),(0,f.jsx)(i,{type:`button`,variant:h===`destructive`?`destructive`:`default`,onClick:()=>{g(),n(!1)},children:p})]})]})}),m={open:!1,title:``,description:``,confirmLabel:t(`confirm`),cancelLabel:t(`cancel`),variant:`default`,resolve:null};function h(){let[e,n]=(0,d.useState)(m),r=(0,d.useCallback)(e=>new Promise(r=>{n({open:!0,title:e.title,description:e.description??``,confirmLabel:e.confirmLabel??t(`confirm`),cancelLabel:e.cancelLabel??t(`cancel`),variant:e.variant??`default`,resolve:e=>{r(e),n(e=>({...e,open:!1,resolve:null}))}})}),[]),i=(0,d.useCallback)(e=>{n(t=>(!e&&t.resolve&&t.resolve(!1),{...t,open:e,resolve:e?t.resolve:null}))},[]);return{confirm:r,ConfirmDialog:(0,d.useCallback)(()=>(0,f.jsx)(p,{open:e.open,onOpenChange:i,title:e.title,description:e.description||void 0,confirmLabel:e.confirmLabel,cancelLabel:e.cancelLabel,variant:e.variant,onConfirm:()=>e.resolve?.(!0),onCancel:()=>e.resolve?.(!1)}),[e,i])}}export{h as t};
@@ -1 +1 @@
1
- import{_ as e,m as t}from"./i18n-C_2dKw6w.js";import{A as n,E as r,M as i,S as a,f as o,h as s,k as c,u as l}from"./dist-BFc_H-lY.js";var u=class extends i{#e;#t=void 0;#n;#r;constructor(e,t){super(),this.#e=e,this.setOptions(t),this.bindMethods(),this.#i()}bindMethods(){this.mutate=this.mutate.bind(this),this.reset=this.reset.bind(this)}setOptions(e){let t=this.options;this.options=this.#e.defaultMutationOptions(e),c(this.options,t)||this.#e.getMutationCache().notify({type:`observerOptionsUpdated`,mutation:this.#n,observer:this}),t?.mutationKey&&this.options.mutationKey&&a(t.mutationKey)!==a(this.options.mutationKey)?this.reset():this.#n?.state.status===`pending`&&this.#n.setOptions(this.options)}onUnsubscribe(){this.hasListeners()||this.#n?.removeObserver(this)}onMutationUpdate(e){this.#i(),this.#a(e)}getCurrentResult(){return this.#t}reset(){this.#n?.removeObserver(this),this.#n=void 0,this.#i(),this.#a()}mutate(e,t){return this.#r=t,this.#n?.removeObserver(this),this.#n=this.#e.getMutationCache().build(this.#e,this.options),this.#n.addObserver(this),this.#n.execute(e)}#i(){let e=this.#n?.state??o();this.#t={...e,isPending:e.status===`pending`,isSuccess:e.status===`success`,isError:e.status===`error`,isIdle:e.status===`idle`,mutate:this.mutate,reset:this.reset}}#a(e){s.batch(()=>{if(this.#r&&this.hasListeners()){let t=this.#t.variables,n=this.#t.context,r={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};if(e?.type===`success`){try{this.#r.onSuccess?.(e.data,t,n,r)}catch(e){Promise.reject(e)}try{this.#r.onSettled?.(e.data,null,t,n,r)}catch(e){Promise.reject(e)}}else if(e?.type===`error`){try{this.#r.onError?.(e.error,t,n,r)}catch(e){Promise.reject(e)}try{this.#r.onSettled?.(void 0,e.error,t,n,r)}catch(e){Promise.reject(e)}}}this.listeners.forEach(e=>{e(this.#t)})})}},d=e(t(),1);function f(e,t){let i=l(t),[a]=d.useState(()=>new u(i,e));d.useEffect(()=>{a.setOptions(e)},[a,e]);let o=d.useSyncExternalStore(d.useCallback(e=>a.subscribe(s.batchCalls(e)),[a]),()=>a.getCurrentResult(),()=>a.getCurrentResult()),c=d.useCallback((e,t)=>{a.mutate(e,t).catch(r)},[a]);if(o.error&&n(a.options.throwOnError,[o.error]))throw o.error;return{...o,mutate:c,mutateAsync:o.mutate}}export{f as t};
1
+ import{_ as e,m as t}from"./i18n-DJg9BPYk.js";import{M as n,O as r,P as i,_ as a,d as o,j as s,p as c,w as l}from"./dist-BCXX7FD-.js";var u=class extends i{#e;#t=void 0;#n;#r;constructor(e,t){super(),this.#e=e,this.setOptions(t),this.bindMethods(),this.#i()}bindMethods(){this.mutate=this.mutate.bind(this),this.reset=this.reset.bind(this)}setOptions(e){let t=this.options;this.options=this.#e.defaultMutationOptions(e),s(this.options,t)||this.#e.getMutationCache().notify({type:`observerOptionsUpdated`,mutation:this.#n,observer:this}),t?.mutationKey&&this.options.mutationKey&&l(t.mutationKey)!==l(this.options.mutationKey)?this.reset():this.#n?.state.status===`pending`&&this.#n.setOptions(this.options)}onUnsubscribe(){this.hasListeners()||this.#n?.removeObserver(this)}onMutationUpdate(e){this.#i(),this.#a(e)}getCurrentResult(){return this.#t}reset(){this.#n?.removeObserver(this),this.#n=void 0,this.#i(),this.#a()}mutate(e,t){return this.#r=t,this.#n?.removeObserver(this),this.#n=this.#e.getMutationCache().build(this.#e,this.options),this.#n.addObserver(this),this.#n.execute(e)}#i(){let e=this.#n?.state??c();this.#t={...e,isPending:e.status===`pending`,isSuccess:e.status===`success`,isError:e.status===`error`,isIdle:e.status===`idle`,mutate:this.mutate,reset:this.reset}}#a(e){a.batch(()=>{if(this.#r&&this.hasListeners()){let t=this.#t.variables,n=this.#t.context,r={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};if(e?.type===`success`){try{this.#r.onSuccess?.(e.data,t,n,r)}catch(e){Promise.reject(e)}try{this.#r.onSettled?.(e.data,null,t,n,r)}catch(e){Promise.reject(e)}}else if(e?.type===`error`){try{this.#r.onError?.(e.error,t,n,r)}catch(e){Promise.reject(e)}try{this.#r.onSettled?.(void 0,e.error,t,n,r)}catch(e){Promise.reject(e)}}}this.listeners.forEach(e=>{e(this.#t)})})}},d=e(t(),1);function f(e,t){let i=o(t),[s]=d.useState(()=>new u(i,e));d.useEffect(()=>{s.setOptions(e)},[s,e]);let c=d.useSyncExternalStore(d.useCallback(e=>s.subscribe(a.batchCalls(e)),[s]),()=>s.getCurrentResult(),()=>s.getCurrentResult()),l=d.useCallback((e,t)=>{s.mutate(e,t).catch(r)},[s]);if(c.error&&n(s.options.throwOnError,[c.error]))throw c.error;return{...c,mutate:l,mutateAsync:c.mutate}}export{f as t};
@@ -0,0 +1 @@
1
+ import{t as e}from"./createLucideIcon-_FMJqZw2.js";var t=e(`X`,[[`path`,{d:`M18 6 6 18`,key:`1bl5f8`}],[`path`,{d:`m6 6 12 12`,key:`d8bk6v`}]]);export{t};
package/dist/index.html CHANGED
@@ -6,24 +6,25 @@
6
6
  <link rel="icon" type="image/svg+xml" href="/logo.svg" />
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
8
  <title>NextClaw</title>
9
- <script type="module" crossorigin src="/assets/index-DAE8Srx-.js"></script>
10
- <link rel="modulepreload" crossorigin href="/assets/i18n-C_2dKw6w.js">
11
- <link rel="modulepreload" crossorigin href="/assets/chunk-JZWAC4HX-DbL4EmiT.js">
12
- <link rel="modulepreload" crossorigin href="/assets/dist-BFc_H-lY.js">
13
- <link rel="modulepreload" crossorigin href="/assets/createLucideIcon-BRLFtf-8.js">
14
- <link rel="modulepreload" crossorigin href="/assets/select-BtIi5fnh.js">
15
- <link rel="modulepreload" crossorigin href="/assets/dist-DP-JKR4G.js">
16
- <link rel="modulepreload" crossorigin href="/assets/react-8EIEQjMP.js">
17
- <link rel="modulepreload" crossorigin href="/assets/useMutation-DSinpgEq.js">
18
- <link rel="modulepreload" crossorigin href="/assets/book-open-C7TAghTk.js">
19
- <link rel="modulepreload" crossorigin href="/assets/external-link-BkJkiWbH.js">
20
- <link rel="modulepreload" crossorigin href="/assets/plus-CYXs3JtZ.js">
21
- <link rel="modulepreload" crossorigin href="/assets/search-DOsLw-P9.js">
22
- <link rel="modulepreload" crossorigin href="/assets/x-Bnco_K8b.js">
23
- <link rel="modulepreload" crossorigin href="/assets/DocBrowserContext-DpgVdRgk.js">
24
- <link rel="modulepreload" crossorigin href="/assets/DocBrowser-NSzgVKka.js">
25
- <link rel="modulepreload" crossorigin href="/assets/config-CMiW0yaK.js">
26
- <link rel="stylesheet" crossorigin href="/assets/index-ChUXhq0G.css">
9
+ <script type="module" crossorigin src="/assets/index-CtlT4E9Y.js"></script>
10
+ <link rel="modulepreload" crossorigin href="/assets/i18n-DJg9BPYk.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/chunk-JZWAC4HX-D5b3Iyas.js">
12
+ <link rel="modulepreload" crossorigin href="/assets/dist-BCXX7FD-.js">
13
+ <link rel="modulepreload" crossorigin href="/assets/createLucideIcon-_FMJqZw2.js">
14
+ <link rel="modulepreload" crossorigin href="/assets/select-xp_Ac8ip.js">
15
+ <link rel="modulepreload" crossorigin href="/assets/dist-B1fpOuON.js">
16
+ <link rel="modulepreload" crossorigin href="/assets/infiniteQueryBehavior-CTcVlD9s.js">
17
+ <link rel="modulepreload" crossorigin href="/assets/react-BB4jko2M.js">
18
+ <link rel="modulepreload" crossorigin href="/assets/useMutation-BjBOKHj_.js">
19
+ <link rel="modulepreload" crossorigin href="/assets/book-open-CJG8Yz3U.js">
20
+ <link rel="modulepreload" crossorigin href="/assets/external-link-b7gAJWYY.js">
21
+ <link rel="modulepreload" crossorigin href="/assets/plus-CR7RfK3H.js">
22
+ <link rel="modulepreload" crossorigin href="/assets/search-C60UA27E.js">
23
+ <link rel="modulepreload" crossorigin href="/assets/x-BfTu-g7D.js">
24
+ <link rel="modulepreload" crossorigin href="/assets/DocBrowserContext-CpiIfhJO.js">
25
+ <link rel="modulepreload" crossorigin href="/assets/DocBrowser-QUZ3nfmH.js">
26
+ <link rel="modulepreload" crossorigin href="/assets/config-zvnxSXSP.js">
27
+ <link rel="stylesheet" crossorigin href="/assets/index-BoJbxdvZ.css">
27
28
  </head>
28
29
 
29
30
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/ui",
3
- "version": "0.12.4",
3
+ "version": "0.12.5",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -28,10 +28,10 @@
28
28
  "tailwind-merge": "^2.5.4",
29
29
  "zod": "^3.23.8",
30
30
  "zustand": "^5.0.2",
31
- "@nextclaw/agent-chat": "0.1.8",
32
- "@nextclaw/ncp-react": "0.4.17",
33
31
  "@nextclaw/ncp": "0.5.0",
34
- "@nextclaw/agent-chat-ui": "0.3.1",
32
+ "@nextclaw/ncp-react": "0.4.18",
33
+ "@nextclaw/agent-chat": "0.1.9",
34
+ "@nextclaw/agent-chat-ui": "0.3.2",
35
35
  "@nextclaw/ncp-http-agent-client": "0.3.12"
36
36
  },
37
37
  "devDependencies": {
@@ -1,17 +1,19 @@
1
1
  import { Button } from '@/components/ui/button';
2
2
  import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog';
3
+ import { Input } from '@/components/ui/input';
4
+ import { Label } from '@/components/ui/label';
3
5
  import { useRemoteStatus } from '@/hooks/useRemoteAccess';
4
6
  import { formatDateTime, t } from '@/lib/i18n';
5
7
  import { useAccountStore } from '@/account/stores/account.store';
6
8
  import { useAppPresenter } from '@/presenter/app-presenter-context';
7
9
  import { KeyRound, LogOut, SquareArrowOutUpRight } from 'lucide-react';
8
- import { useEffect } from 'react';
10
+ import { useEffect, useState } from 'react';
9
11
 
10
- function AccountValueRow(props: { label: string; value?: string | null }) {
12
+ function AccountValueRow({ label, value }: { label: string; value?: string | null }) {
11
13
  return (
12
14
  <div className="flex items-start justify-between gap-4 py-2 text-sm">
13
- <span className="text-gray-500">{props.label}</span>
14
- <span className="text-right text-gray-900">{props.value?.trim() || '-'}</span>
15
+ <span className="text-gray-500">{label}</span>
16
+ <span className="text-right text-gray-900">{value?.trim() || '-'}</span>
15
17
  </div>
16
18
  );
17
19
  }
@@ -25,11 +27,15 @@ export function AccountPanel() {
25
27
  const authExpiresAt = useAccountStore((state) => state.authExpiresAt);
26
28
  const authStatusMessage = useAccountStore((state) => state.authStatusMessage);
27
29
  const status = remoteStatus.data;
30
+ const [usernameDraft, setUsernameDraft] = useState('');
31
+ const [savingUsername, setSavingUsername] = useState(false);
28
32
 
29
33
  useEffect(() => {
30
34
  presenter.accountManager.syncRemoteStatus(status);
31
35
  }, [presenter, status]);
32
36
 
37
+ const canSubmitUsername = !savingUsername && usernameDraft.trim().length > 0 && !status?.account.username;
38
+
33
39
  return (
34
40
  <Dialog open={panelOpen} onOpenChange={(open) => (open ? presenter.accountManager.openAccountPanel() : presenter.accountManager.closeAccountPanel())}>
35
41
  <DialogContent className="max-w-xl">
@@ -49,8 +55,44 @@ export function AccountPanel() {
49
55
  </div>
50
56
  <div className="rounded-2xl border border-gray-200 bg-gray-50 px-4 py-3">
51
57
  <AccountValueRow label={t('remoteAccountEmail')} value={status.account.email} />
58
+ <AccountValueRow label={t('remoteAccountUsername')} value={status.account.username} />
52
59
  <AccountValueRow label={t('remoteAccountRole')} value={status.account.role} />
53
60
  </div>
61
+ {status.account.username ? (
62
+ <p className="text-xs text-gray-500">{t('remoteAccountUsernameLockedHelp')}</p>
63
+ ) : (
64
+ <div className="rounded-2xl border border-amber-200 bg-amber-50 px-4 py-4">
65
+ <p className="text-sm font-medium text-amber-900">{t('remoteAccountUsernameRequiredTitle')}</p>
66
+ <p className="mt-1 text-sm text-amber-800">{t('remoteAccountUsernameRequiredDescription')}</p>
67
+ <div className="mt-4 space-y-2">
68
+ <Label htmlFor="account-panel-username">{t('remoteAccountUsername')}</Label>
69
+ <Input
70
+ id="account-panel-username"
71
+ value={usernameDraft}
72
+ onChange={(event) => setUsernameDraft(event.target.value)}
73
+ placeholder={t('remoteAccountUsernamePlaceholder')}
74
+ autoCapitalize="none"
75
+ autoCorrect="off"
76
+ spellCheck={false}
77
+ />
78
+ </div>
79
+ <div className="mt-4 flex flex-wrap gap-3">
80
+ <Button
81
+ disabled={!canSubmitUsername}
82
+ onClick={async () => {
83
+ setSavingUsername(true);
84
+ try {
85
+ await presenter.accountManager.updateUsername(usernameDraft);
86
+ } finally {
87
+ setSavingUsername(false);
88
+ }
89
+ }}
90
+ >
91
+ {savingUsername ? t('remoteAccountUsernameSaving') : t('remoteAccountUsernameSave')}
92
+ </Button>
93
+ </div>
94
+ </div>
95
+ )}
54
96
  <div className="flex flex-wrap gap-3">
55
97
  <Button onClick={() => void presenter.accountManager.openNextClawWeb()}>
56
98
  <SquareArrowOutUpRight className="mr-2 h-4 w-4" />
@@ -1,4 +1,4 @@
1
- import { logoutRemote, pollRemoteBrowserAuth, startRemoteBrowserAuth } from '@/api/remote';
1
+ import { logoutRemote, pollRemoteBrowserAuth, startRemoteBrowserAuth, updateRemoteAccountProfile } from '@/api/remote';
2
2
  import type { RemoteAccessView } from '@/api/remote.types';
3
3
  import type { AccountPendingAction } from '@/account/stores/account.store';
4
4
  import { useAccountStore } from '@/account/stores/account.store';
@@ -57,12 +57,14 @@ export class AccountManager {
57
57
  pendingAction?: AccountPendingAction;
58
58
  }) => {
59
59
  try {
60
+ const apiBase = params?.apiBase;
61
+ const pendingAction = params?.pendingAction;
60
62
  const status = params?.status ?? (await ensureRemoteStatus());
61
- if (params?.pendingAction) {
62
- useAccountStore.getState().setPendingAction(params.pendingAction);
63
+ if (pendingAction) {
64
+ useAccountStore.getState().setPendingAction(pendingAction);
63
65
  }
64
66
  const result = await startRemoteBrowserAuth({
65
- apiBase: resolveRemotePlatformApiBase(status, params?.apiBase)
67
+ apiBase: resolveRemotePlatformApiBase(status, apiBase)
66
68
  });
67
69
  useAccountStore.getState().beginBrowserAuth({
68
70
  sessionId: result.sessionId,
@@ -103,6 +105,19 @@ export class AccountManager {
103
105
  }
104
106
  };
105
107
 
108
+ updateUsername = async (username: string) => {
109
+ try {
110
+ await updateRemoteAccountProfile({
111
+ username: username.trim()
112
+ });
113
+ await refreshRemoteStatus();
114
+ toast.success(t('remoteAccountUsernameSetSuccess'));
115
+ } catch (error) {
116
+ const message = error instanceof Error ? error.message : t('remoteAccountUsernameSetFailed');
117
+ toast.error(`${t('remoteAccountUsernameSetFailed')}: ${message}`);
118
+ }
119
+ };
120
+
106
121
  openNextClawWeb = async () => {
107
122
  const status = await ensureRemoteStatus();
108
123
  const webBase = resolveRemoteWebBase(status);
package/src/api/remote.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { api } from './client';
2
2
  import type {
3
3
  RemoteAccessView,
4
+ RemoteAccountProfileUpdateRequest,
4
5
  RemoteBrowserAuthPollRequest,
5
6
  RemoteBrowserAuthPollResult,
6
7
  RemoteBrowserAuthStartRequest,
@@ -60,6 +61,14 @@ export async function logoutRemote(): Promise<RemoteAccessView> {
60
61
  return response.data;
61
62
  }
62
63
 
64
+ export async function updateRemoteAccountProfile(data: RemoteAccountProfileUpdateRequest): Promise<RemoteAccessView> {
65
+ const response = await api.put<RemoteAccessView>('/api/remote/account/profile', data);
66
+ if (!response.ok) {
67
+ throw new Error(response.error.message);
68
+ }
69
+ return response.data;
70
+ }
71
+
63
72
  export async function updateRemoteSettings(data: RemoteSettingsUpdateRequest): Promise<RemoteAccessView> {
64
73
  const response = await api.put<RemoteAccessView>('/api/remote/settings', data);
65
74
  if (!response.ok) {
@@ -1,11 +1,16 @@
1
1
  export type RemoteAccountView = {
2
2
  loggedIn: boolean;
3
3
  email?: string;
4
+ username?: string | null;
4
5
  role?: string;
5
6
  platformBase?: string | null;
6
7
  apiBase?: string | null;
7
8
  };
8
9
 
10
+ export type RemoteAccountProfileUpdateRequest = {
11
+ username: string;
12
+ };
13
+
9
14
  export type RemoteRuntimeView = {
10
15
  enabled: boolean;
11
16
  mode: "service" | "foreground";