@nextclaw/ui 0.10.5 → 0.11.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.
- package/CHANGELOG.md +15 -0
- package/dist/assets/{ChannelsList-Nu7Ig6_-.js → ChannelsList-BqsOYnXz.js} +1 -1
- package/dist/assets/{ChatPage-CBCFSk4e.js → ChatPage-CJBYKR-Y.js} +24 -24
- package/dist/assets/{DocBrowser-3CfKmJA6.js → DocBrowser-BmL0QXBZ.js} +1 -1
- package/dist/assets/{LogoBadge-DdthDJOp.js → LogoBadge-C1HiPZPf.js} +1 -1
- package/dist/assets/{MarketplacePage-inGGiv1T.js → MarketplacePage-BIRP0NRS.js} +1 -1
- package/dist/assets/{McpMarketplacePage-Dg8GSZh6.js → McpMarketplacePage-CLHFnNBd.js} +1 -1
- package/dist/assets/{ModelConfig-DyQ6cC92.js → ModelConfig-LQSR58tc.js} +1 -1
- package/dist/assets/{ProvidersList-B2T8Lc_i.js → ProvidersList-CwI-mxah.js} +1 -1
- package/dist/assets/{RemoteAccessPage-C9LxgK-C.js → RemoteAccessPage-Cw5BqZb6.js} +1 -1
- package/dist/assets/{RuntimeConfig-Ey4VIqTW.js → RuntimeConfig-DbowSRAb.js} +1 -1
- package/dist/assets/{SearchConfig-R1BcCLWO.js → SearchConfig-Chzo_JGs.js} +1 -1
- package/dist/assets/{SecretsConfig-D-jZMHeY.js → SecretsConfig-CEIbjZYA.js} +1 -1
- package/dist/assets/{SessionsConfig-Cawoh4_2.js → SessionsConfig-BR8GfGWL.js} +1 -1
- package/dist/assets/{chat-message-BbuIK4dQ.js → chat-message-CPG7zxRR.js} +1 -1
- package/dist/assets/{index-BulnQWr6.js → index-j6A_-1b6.js} +2 -2
- package/dist/assets/{label-C7yzBvzK.js → label-GACO2RzW.js} +1 -1
- package/dist/assets/{page-layout-DF0xpax2.js → page-layout-DjXaK3A3.js} +1 -1
- package/dist/assets/{popover-DjaScZDJ.js → popover-DTaFiTmU.js} +1 -1
- package/dist/assets/{security-config-Bg2eriNx.js → security-config-Dk-yoKvK.js} +1 -1
- package/dist/assets/{skeleton-DycBJAJF.js → skeleton-Dm2xOBSA.js} +1 -1
- package/dist/assets/{status-dot-B9opOZ22.js → status-dot-IWEBezqb.js} +1 -1
- package/dist/assets/{switch-l1P0ev4D.js → switch-DCHAJSrA.js} +1 -1
- package/dist/assets/{tabs-custom-BG9y2JhC.js → tabs-custom-DKSbDSB9.js} +1 -1
- package/dist/assets/{useConfirmDialog-DTducNfn.js → useConfirmDialog-ByJ8A8n7.js} +1 -1
- package/dist/index.html +1 -1
- package/package.json +5 -5
- package/src/api/ncp-attachments.ts +12 -12
- package/src/api/types.ts +4 -4
- package/src/components/chat/adapters/chat-message.adapter.test.ts +39 -0
- package/src/components/chat/adapters/chat-message.adapter.ts +56 -0
- package/src/components/chat/chat-composer-state.test.ts +4 -4
- package/src/components/chat/chat-composer-state.ts +1 -1
- package/src/components/chat/containers/chat-input-bar.container.tsx +2 -2
- package/src/components/chat/ncp/ncp-chat-input.manager.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as s,j as o}from"./vendor-CNhxtHCf.js";import{c as t}from"./index-
|
|
1
|
+
import{r as s,j as o}from"./vendor-CNhxtHCf.js";import{c as t}from"./index-j6A_-1b6.js";const l=s.forwardRef(({className:e,...a},r)=>o.jsx("label",{ref:r,className:t("text-sm font-medium leading-none text-gray-700 peer-disabled:cursor-not-allowed peer-disabled:opacity-70",e),...a}));l.displayName="Label";export{l as L};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./vendor-CNhxtHCf.js";import{c as l}from"./index-
|
|
1
|
+
import{j as e}from"./vendor-CNhxtHCf.js";import{c as l}from"./index-j6A_-1b6.js";function x({children:t,fullHeight:s=!1,className:a}){return e.jsx("div",{className:l("animate-fade-in",s?"h-[calc(100vh-80px)] w-full flex flex-col":"pb-16",a),children:t})}function c({title:t,description:s,actions:a,className:r}){return e.jsxs("div",{className:l("flex items-center justify-between mb-6 shrink-0",r),children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-xl font-semibold text-gray-900",children:t}),s&&e.jsx("p",{className:"text-sm text-gray-500 mt-1",children:s})]}),a&&e.jsx("div",{className:"flex items-center gap-2 shrink-0",children:a})]})}export{x as P,c as a};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as l,aK as L,j as c,aL as z,aM as G,aN as A,aO as O,aP as P,aQ as _,aR as w,aS as b,aT as H,aU as K,aV as U,aW as V,aX as W,aY as Z,aZ as Q,a_ as X,a$ as Y,b0 as q}from"./vendor-CNhxtHCf.js";import{c as B}from"./index-
|
|
1
|
+
import{r as l,aK as L,j as c,aL as z,aM as G,aN as A,aO as O,aP as P,aQ as _,aR as w,aS as b,aT as H,aU as K,aV as U,aW as V,aX as W,aY as Z,aZ as Q,a_ as X,a$ as Y,b0 as q}from"./vendor-CNhxtHCf.js";import{c as B}from"./index-j6A_-1b6.js";var m="Popover",[E]=K(m,[w]),g=w(),[J,d]=E(m),j=e=>{const{__scopePopover:n,children:t,open:a,defaultOpen:o,onOpenChange:r,modal:s=!1}=e,i=g(n),p=l.useRef(null),[u,h]=l.useState(!1),[C,f]=L({prop:a,defaultProp:o??!1,onChange:r,caller:m});return c.jsx(z,{...i,children:c.jsx(J,{scope:n,contentId:G(),triggerRef:p,open:C,onOpenChange:f,onOpenToggle:l.useCallback(()=>f(x=>!x),[f]),hasCustomAnchor:u,onCustomAnchorAdd:l.useCallback(()=>h(!0),[]),onCustomAnchorRemove:l.useCallback(()=>h(!1),[]),modal:s,children:t})})};j.displayName=m;var N="PopoverAnchor",y=l.forwardRef((e,n)=>{const{__scopePopover:t,...a}=e,o=d(N,t),r=g(t),{onCustomAnchorAdd:s,onCustomAnchorRemove:i}=o;return l.useEffect(()=>(s(),()=>i()),[s,i]),c.jsx(_,{...r,...a,ref:n})});y.displayName=N;var F="PopoverTrigger",S=l.forwardRef((e,n)=>{const{__scopePopover:t,...a}=e,o=d(F,t),r=g(t),s=A(n,o.triggerRef),i=c.jsx(O.button,{type:"button","aria-haspopup":"dialog","aria-expanded":o.open,"aria-controls":o.contentId,"data-state":I(o.open),...a,ref:s,onClick:P(e.onClick,o.onOpenToggle)});return o.hasCustomAnchor?i:c.jsx(_,{asChild:!0,...r,children:i})});S.displayName=F;var R="PopoverPortal",[ee,oe]=E(R,{forceMount:void 0}),M=e=>{const{__scopePopover:n,forceMount:t,children:a,container:o}=e,r=d(R,n);return c.jsx(ee,{scope:n,forceMount:t,children:c.jsx(b,{present:t||r.open,children:c.jsx(H,{asChild:!0,container:o,children:a})})})};M.displayName=R;var v="PopoverContent",T=l.forwardRef((e,n)=>{const t=oe(v,e.__scopePopover),{forceMount:a=t.forceMount,...o}=e,r=d(v,e.__scopePopover);return c.jsx(b,{present:a||r.open,children:r.modal?c.jsx(re,{...o,ref:n}):c.jsx(ne,{...o,ref:n})})});T.displayName=v;var te=W("PopoverContent.RemoveScroll"),re=l.forwardRef((e,n)=>{const t=d(v,e.__scopePopover),a=l.useRef(null),o=A(n,a),r=l.useRef(!1);return l.useEffect(()=>{const s=a.current;if(s)return U(s)},[]),c.jsx(V,{as:te,allowPinchZoom:!0,children:c.jsx(D,{...e,ref:o,trapFocus:t.open,disableOutsidePointerEvents:!0,onCloseAutoFocus:P(e.onCloseAutoFocus,s=>{var i;s.preventDefault(),r.current||(i=t.triggerRef.current)==null||i.focus()}),onPointerDownOutside:P(e.onPointerDownOutside,s=>{const i=s.detail.originalEvent,p=i.button===0&&i.ctrlKey===!0,u=i.button===2||p;r.current=u},{checkForDefaultPrevented:!1}),onFocusOutside:P(e.onFocusOutside,s=>s.preventDefault(),{checkForDefaultPrevented:!1})})})}),ne=l.forwardRef((e,n)=>{const t=d(v,e.__scopePopover),a=l.useRef(!1),o=l.useRef(!1);return c.jsx(D,{...e,ref:n,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:r=>{var s,i;(s=e.onCloseAutoFocus)==null||s.call(e,r),r.defaultPrevented||(a.current||(i=t.triggerRef.current)==null||i.focus(),r.preventDefault()),a.current=!1,o.current=!1},onInteractOutside:r=>{var p,u;(p=e.onInteractOutside)==null||p.call(e,r),r.defaultPrevented||(a.current=!0,r.detail.originalEvent.type==="pointerdown"&&(o.current=!0));const s=r.target;((u=t.triggerRef.current)==null?void 0:u.contains(s))&&r.preventDefault(),r.detail.originalEvent.type==="focusin"&&o.current&&r.preventDefault()}})}),D=l.forwardRef((e,n)=>{const{__scopePopover:t,trapFocus:a,onOpenAutoFocus:o,onCloseAutoFocus:r,disableOutsidePointerEvents:s,onEscapeKeyDown:i,onPointerDownOutside:p,onFocusOutside:u,onInteractOutside:h,...C}=e,f=d(v,t),x=g(t);return Z(),c.jsx(Q,{asChild:!0,loop:!0,trapped:a,onMountAutoFocus:o,onUnmountAutoFocus:r,children:c.jsx(X,{asChild:!0,disableOutsidePointerEvents:s,onInteractOutside:h,onEscapeKeyDown:i,onPointerDownOutside:p,onFocusOutside:u,onDismiss:()=>f.onOpenChange(!1),children:c.jsx(Y,{"data-state":I(f.open),role:"dialog",id:f.contentId,...x,...C,ref:n,style:{...C.style,"--radix-popover-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-popover-content-available-width":"var(--radix-popper-available-width)","--radix-popover-content-available-height":"var(--radix-popper-available-height)","--radix-popover-trigger-width":"var(--radix-popper-anchor-width)","--radix-popover-trigger-height":"var(--radix-popper-anchor-height)"}})})})}),k="PopoverClose",ae=l.forwardRef((e,n)=>{const{__scopePopover:t,...a}=e,o=d(k,t);return c.jsx(O.button,{type:"button",...a,ref:n,onClick:P(e.onClick,()=>o.onOpenChange(!1))})});ae.displayName=k;var se="PopoverArrow",ce=l.forwardRef((e,n)=>{const{__scopePopover:t,...a}=e,o=g(t);return c.jsx(q,{...o,...a,ref:n})});ce.displayName=se;function I(e){return e?"open":"closed"}var ie=j,ve=y,le=S,pe=M,$=T;const Pe=ie,ge=le,ue=l.forwardRef(({className:e,sideOffset:n=8,align:t="start",...a},o)=>c.jsx(pe,{children:c.jsx($,{ref:o,sideOffset:n,align:t,className:B("z-[var(--z-popover,50)] w-72 overflow-hidden rounded-2xl border border-gray-200/50 bg-white p-4 shadow-lg animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",e),...a})}));ue.displayName=$.displayName;export{ve as A,$ as C,pe as P,ie as R,le as T,Pe as a,ge as b,ue as c};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as c,j as e,e as M}from"./vendor-CNhxtHCf.js";import{a9 as O,aa as R,ab as I,ac as B,ad as _,C as u,a6 as h,a7 as x,t as s,a8 as m,J as p,B as j,I as l}from"./index-
|
|
1
|
+
import{r as c,j as e,e as M}from"./vendor-CNhxtHCf.js";import{a9 as O,aa as R,ab as I,ac as B,ad as _,C as u,a6 as h,a7 as x,t as s,a8 as m,J as p,B as j,I as l}from"./index-j6A_-1b6.js";import{L as o}from"./label-GACO2RzW.js";import{S as G}from"./switch-DCHAJSrA.js";import{P as J,a as V}from"./page-layout-DjXaK3A3.js";const W=8;function A(r){return r.trim().length>=W}function L(r,n){return r!==n?(M.error(s("authPasswordMismatch")),!1):!0}function q(){const r=O(),n=R(),S=I(),g=B(),y=_(),[f,U]=c.useState(""),[i,N]=c.useState(""),[w,b]=c.useState(""),[d,v]=c.useState(""),[P,C]=c.useState(""),t=r.data,E=f.trim().length>0&&A(i)&&i===w&&!n.isPending,D=A(d)&&d===P&&!g.isPending,T=async()=>{if(L(i,w))try{await n.mutateAsync({username:f.trim(),password:i}),N(""),b("")}catch{}},F=async()=>{if(L(d,P))try{await g.mutateAsync({password:d}),v(""),C("")}catch{}},H=async a=>{try{await S.mutateAsync({enabled:a})}catch{}},k=async()=>{try{await y.mutateAsync()}catch{}};return r.isLoading&&!t?e.jsxs(u,{children:[e.jsxs(h,{children:[e.jsx(x,{children:s("authSecurityTitle")}),e.jsx(m,{children:s("authSecurityDescription")})]}),e.jsx(p,{className:"text-sm text-gray-500",children:s("loading")})]}):r.isError||!t?e.jsxs(u,{children:[e.jsxs(h,{children:[e.jsx(x,{children:s("authSecurityTitle")}),e.jsx(m,{children:s("authSecurityDescription")})]}),e.jsxs(p,{className:"space-y-4",children:[e.jsx("p",{className:"text-sm text-gray-500",children:s("authStatusLoadFailed")}),e.jsx(j,{variant:"outline",onClick:()=>{r.refetch()},children:s("authRetryStatus")})]})]}):t.configured?e.jsxs(u,{children:[e.jsxs(h,{children:[e.jsx(x,{children:s("authSecurityTitle")}),e.jsx(m,{children:s("authSecurityDescription")})]}),e.jsxs(p,{className:"space-y-6",children:[e.jsxs("div",{className:"rounded-xl border border-gray-200 p-4",children:[e.jsxs("div",{className:"flex flex-col gap-4 md:flex-row md:items-start md:justify-between",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-sm font-medium text-gray-900",children:s("authStatusLabel")}),e.jsx("p",{className:"text-sm text-gray-600",children:s("authStatusConfiguredUser").replace("{username}",t.username??"")}),e.jsx("p",{className:"text-xs text-gray-500",children:s("authUsernameFixedHelp")})]}),e.jsx("span",{className:"inline-flex items-center rounded-full bg-gray-100 px-3 py-1 text-xs font-medium text-gray-700",children:t.enabled?s("enabled"):s("disabled")})]}),e.jsxs("div",{className:"mt-4 flex flex-col gap-4 border-t border-gray-200 pt-4 md:flex-row md:items-center md:justify-between",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-sm font-medium text-gray-900",children:s("authEnableLabel")}),e.jsx("p",{className:"text-xs text-gray-500",children:t.enabled?s("authEnableOnHelp"):s("authEnableOffHelp")})]}),e.jsx(G,{checked:t.enabled,disabled:S.isPending,onCheckedChange:a=>{H(a)}})]})]}),e.jsxs("div",{className:"rounded-xl border border-gray-200 p-4 space-y-4",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-sm font-medium text-gray-900",children:s("authPasswordSectionTitle")}),e.jsx("p",{className:"text-xs text-gray-500",children:s("authPasswordSectionDescription")})]}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(o,{htmlFor:"auth-password-next",children:s("authPassword")}),e.jsx(l,{id:"auth-password-next",type:"password",value:d,onChange:a=>v(a.target.value),placeholder:s("authPasswordPlaceholder")})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(o,{htmlFor:"auth-password-confirm",children:s("authConfirmPassword")}),e.jsx(l,{id:"auth-password-confirm",type:"password",value:P,onChange:a=>C(a.target.value),placeholder:s("authConfirmPasswordPlaceholder")})]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx(j,{type:"button",disabled:!D,onClick:()=>void F(),children:g.isPending?s("authPasswordUpdating"):s("authPasswordAction")}),t.enabled&&t.authenticated?e.jsx(j,{type:"button",variant:"outline",disabled:y.isPending,onClick:()=>void k(),children:y.isPending?s("authLoggingOut"):s("authLogoutAction")}):null]}),e.jsx("p",{className:"text-xs text-gray-500",children:s("authSessionMemoryNotice")})]})]})]}):e.jsxs(u,{children:[e.jsxs(h,{children:[e.jsx(x,{children:s("authSecurityTitle")}),e.jsx(m,{children:s("authSecurityDescription")})]}),e.jsxs(p,{className:"space-y-5",children:[e.jsxs("div",{className:"rounded-xl border border-dashed border-gray-200 bg-gray-50/70 p-4",children:[e.jsx("p",{className:"text-sm font-medium text-gray-900",children:s("authSetupTitle")}),e.jsx("p",{className:"mt-1 text-sm text-gray-500",children:s("authSetupDescription")})]}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(o,{htmlFor:"auth-setup-username",children:s("authUsername")}),e.jsx(l,{id:"auth-setup-username",value:f,onChange:a=>U(a.target.value),placeholder:s("authUsernamePlaceholder")})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(o,{htmlFor:"auth-setup-password",children:s("authPassword")}),e.jsx(l,{id:"auth-setup-password",type:"password",value:i,onChange:a=>N(a.target.value),placeholder:s("authPasswordPlaceholder")})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(o,{htmlFor:"auth-setup-confirm",children:s("authConfirmPassword")}),e.jsx(l,{id:"auth-setup-confirm",type:"password",value:w,onChange:a=>b(a.target.value),placeholder:s("authConfirmPasswordPlaceholder")}),e.jsx("p",{className:"text-xs text-gray-500",children:s("authPasswordMinLengthHint")})]}),e.jsx(j,{type:"button",disabled:!E,onClick:()=>void T(),children:n.isPending?s("authSettingUp"):s("authSetupAction")})]})]})}function Z(){return e.jsxs(J,{className:"space-y-6",children:[e.jsx(V,{title:s("authSecurityTitle"),description:s("authSecurityDescription")}),e.jsx(q,{})]})}export{Z as SecurityConfig};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as t}from"./vendor-CNhxtHCf.js";import{c as o}from"./index-
|
|
1
|
+
import{j as t}from"./vendor-CNhxtHCf.js";import{c as o}from"./index-j6A_-1b6.js";function m({className:e,...s}){return t.jsx("div",{className:o("animate-pulse rounded-md bg-slate-200",e),...s})}export{m as S};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./vendor-CNhxtHCf.js";import{c as a}from"./index-
|
|
1
|
+
import{j as e}from"./vendor-CNhxtHCf.js";import{c as a}from"./index-j6A_-1b6.js";const n={active:{dot:"bg-emerald-500",text:"text-emerald-600",bg:"bg-emerald-50"},ready:{dot:"bg-emerald-500",text:"text-emerald-600",bg:"bg-emerald-50"},inactive:{dot:"bg-gray-300",text:"text-gray-400",bg:"bg-gray-100/80"},setup:{dot:"bg-gray-300",text:"text-gray-400",bg:"bg-gray-100/80"},warning:{dot:"bg-amber-400",text:"text-amber-600",bg:"bg-amber-50"}};function m({status:r,label:s,className:g}){const t=n[r];return e.jsxs("div",{className:a("inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full px-2 py-0.5",t.bg,g),children:[e.jsx("span",{className:a("h-1.5 w-1.5 rounded-full",t.dot)}),e.jsx("span",{className:a("text-[11px] font-medium",t.text),children:s})]})}export{m as S};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e,j as i}from"./vendor-CNhxtHCf.js";import{c as t}from"./index-
|
|
1
|
+
import{r as e,j as i}from"./vendor-CNhxtHCf.js";import{c as t}from"./index-j6A_-1b6.js";const l=e.forwardRef(({className:o,checked:r=!1,onCheckedChange:s,...a},n)=>i.jsx("button",{type:"button",role:"switch","aria-checked":r,ref:n,className:t("peer inline-flex h-[22px] w-10 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors duration-fast focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-white disabled:cursor-not-allowed disabled:opacity-50",r?"bg-primary":"bg-gray-200/80 hover:bg-gray-300/80",o),onClick:()=>s==null?void 0:s(!r),...a,children:i.jsx("span",{className:t("pointer-events-none block h-5 w-5 rounded-full bg-white shadow-md ring-0 transition-transform duration-fast",r?"translate-x-5":"translate-x-0")})}));l.displayName="Switch";export{l as S};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./vendor-CNhxtHCf.js";import{as as m,c as s}from"./index-
|
|
1
|
+
import{j as e}from"./vendor-CNhxtHCf.js";import{as as m,c as s}from"./index-j6A_-1b6.js";function c({tabs:a,activeTab:i,onChange:o,className:n}){return e.jsx("div",{className:s("flex items-center gap-6 border-b border-gray-200/60 mb-6",n),children:a.map(t=>{const r=i===t.id;return e.jsxs("button",{onClick:()=>o(t.id),className:s("relative pb-3 text-[14px] font-medium transition-all duration-fast flex items-center gap-1.5",r?"text-gray-900":"text-gray-600 hover:text-gray-900"),children:[t.label,t.count!==void 0&&e.jsx("span",{className:s("text-[11px] font-medium","text-gray-500"),children:m(t.count)}),r&&e.jsx("div",{className:"absolute bottom-0 left-0 right-0 h-[2px] bg-primary rounded-full"})]},t.id)})})}export{c as T};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as a,r as t}from"./vendor-CNhxtHCf.js";import{am as p,an as C,ao as h,ap as x,aq as g,ar as D,B as d,t as i}from"./index-
|
|
1
|
+
import{j as a,r as t}from"./vendor-CNhxtHCf.js";import{am as p,an as C,ao as h,ap as x,aq as g,ar as D,B as d,t as i}from"./index-j6A_-1b6.js";const j=({open:l,onOpenChange:r,title:c,description:o,confirmLabel:s=i("confirm"),cancelLabel:e=i("cancel"),variant:n="default",onConfirm:u,onCancel:f})=>{const m=()=>{u(),r(!1)},v=()=>{f(),r(!1)};return a.jsx(p,{open:l,onOpenChange:r,children:a.jsxs(C,{className:"[&>:last-child]:hidden",onCloseAutoFocus:b=>b.preventDefault(),children:[a.jsxs(h,{children:[a.jsx(x,{children:c}),o?a.jsx(g,{children:o}):null]}),a.jsxs(D,{className:"gap-2 sm:gap-0",children:[a.jsx(d,{type:"button",variant:"outline",onClick:v,children:e}),a.jsx(d,{type:"button",variant:n==="destructive"?"destructive":"default",onClick:m,children:s})]})]})})},L={open:!1,title:"",description:"",confirmLabel:i("confirm"),cancelLabel:i("cancel"),variant:"default",resolve:null};function y(){const[l,r]=t.useState(L),c=t.useCallback(e=>new Promise(n=>{r({open:!0,title:e.title,description:e.description??"",confirmLabel:e.confirmLabel??i("confirm"),cancelLabel:e.cancelLabel??i("cancel"),variant:e.variant??"default",resolve:u=>{n(u),r(f=>({...f,open:!1,resolve:null}))}})}),[]),o=t.useCallback(e=>{r(n=>(!e&&n.resolve&&n.resolve(!1),{...n,open:e,resolve:e?n.resolve:null}))},[]),s=t.useCallback(()=>a.jsx(j,{open:l.open,onOpenChange:o,title:l.title,description:l.description||void 0,confirmLabel:l.confirmLabel,cancelLabel:l.cancelLabel,variant:l.variant,onConfirm:()=>{var e;return(e=l.resolve)==null?void 0:e.call(l,!0)},onCancel:()=>{var e;return(e=l.resolve)==null?void 0:e.call(l,!1)}}),[l,o]);return{confirm:c,ConfirmDialog:s}}export{y as u};
|
package/dist/index.html
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
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-
|
|
9
|
+
<script type="module" crossorigin src="/assets/index-j6A_-1b6.js"></script>
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/vendor-CNhxtHCf.js">
|
|
11
11
|
<link rel="stylesheet" crossorigin href="/assets/index-kaPUhd-8.css">
|
|
12
12
|
</head>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"tailwind-merge": "^2.5.4",
|
|
29
29
|
"zod": "^3.23.8",
|
|
30
30
|
"zustand": "^5.0.2",
|
|
31
|
-
"@nextclaw/ncp": "0.
|
|
32
|
-
"@nextclaw/
|
|
31
|
+
"@nextclaw/ncp": "0.4.0",
|
|
32
|
+
"@nextclaw/ncp-react": "0.4.0",
|
|
33
|
+
"@nextclaw/ncp-http-agent-client": "0.3.4",
|
|
33
34
|
"@nextclaw/agent-chat-ui": "0.2.5",
|
|
34
|
-
"@nextclaw/
|
|
35
|
-
"@nextclaw/ncp-react": "0.3.6"
|
|
35
|
+
"@nextclaw/agent-chat": "0.1.3"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@testing-library/react": "^16.3.0",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { NcpDraftAttachment } from "@nextclaw/ncp-react";
|
|
2
2
|
import { API_BASE } from "./api-base";
|
|
3
|
-
import type { ApiResponse,
|
|
3
|
+
import type { ApiResponse, NcpAssetPutView } from "./types";
|
|
4
4
|
|
|
5
5
|
function readErrorMessage(payload: unknown, fallback: string): string {
|
|
6
6
|
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
|
|
@@ -14,28 +14,28 @@ function readErrorMessage(payload: unknown, fallback: string): string {
|
|
|
14
14
|
return typeof message === "string" && message.trim().length > 0 ? message : fallback;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export async function
|
|
17
|
+
export async function uploadNcpAssets(files: File[]): Promise<NcpDraftAttachment[]> {
|
|
18
18
|
const formData = new FormData();
|
|
19
19
|
for (const file of files) {
|
|
20
20
|
formData.append("files", file);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
const response = await fetch(`${API_BASE}/api/ncp/
|
|
23
|
+
const response = await fetch(`${API_BASE}/api/ncp/assets`, {
|
|
24
24
|
method: "POST",
|
|
25
25
|
body: formData,
|
|
26
26
|
credentials: "include",
|
|
27
27
|
});
|
|
28
|
-
const payload = (await response.json()) as ApiResponse<
|
|
28
|
+
const payload = (await response.json()) as ApiResponse<NcpAssetPutView>;
|
|
29
29
|
if (!response.ok || !payload.ok) {
|
|
30
|
-
throw new Error(readErrorMessage(payload, "Failed to
|
|
30
|
+
throw new Error(readErrorMessage(payload, "Failed to put assets."));
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
return payload.data.
|
|
34
|
-
id:
|
|
35
|
-
name:
|
|
36
|
-
mimeType:
|
|
37
|
-
sizeBytes:
|
|
38
|
-
|
|
39
|
-
url:
|
|
33
|
+
return payload.data.assets.map((asset) => ({
|
|
34
|
+
id: asset.id,
|
|
35
|
+
name: asset.name,
|
|
36
|
+
mimeType: asset.mimeType,
|
|
37
|
+
sizeBytes: asset.sizeBytes,
|
|
38
|
+
assetUri: asset.assetUri,
|
|
39
|
+
url: asset.url,
|
|
40
40
|
}));
|
|
41
41
|
}
|
package/src/api/types.ts
CHANGED
|
@@ -259,17 +259,17 @@ export type NcpSessionMessagesView = {
|
|
|
259
259
|
total: number;
|
|
260
260
|
};
|
|
261
261
|
|
|
262
|
-
export type
|
|
262
|
+
export type NcpAssetView = {
|
|
263
263
|
id: string;
|
|
264
264
|
name: string;
|
|
265
265
|
mimeType: string;
|
|
266
266
|
sizeBytes: number;
|
|
267
|
-
|
|
267
|
+
assetUri: string;
|
|
268
268
|
url: string;
|
|
269
269
|
};
|
|
270
270
|
|
|
271
|
-
export type
|
|
272
|
-
|
|
271
|
+
export type NcpAssetPutView = {
|
|
272
|
+
assets: NcpAssetView[];
|
|
273
273
|
};
|
|
274
274
|
|
|
275
275
|
export type NcpSessionStatusView = NcpSessionStatus;
|
|
@@ -191,3 +191,42 @@ it("keeps named non-image files as downloadable attachments", () => {
|
|
|
191
191
|
},
|
|
192
192
|
});
|
|
193
193
|
});
|
|
194
|
+
|
|
195
|
+
it("renders asset tool results as previewable files", () => {
|
|
196
|
+
const adapted = adapt([
|
|
197
|
+
{
|
|
198
|
+
id: "assistant-asset",
|
|
199
|
+
role: "assistant",
|
|
200
|
+
parts: [
|
|
201
|
+
{
|
|
202
|
+
type: "tool-invocation",
|
|
203
|
+
toolInvocation: {
|
|
204
|
+
status: ToolInvocationStatus.RESULT,
|
|
205
|
+
toolCallId: "call-asset-1",
|
|
206
|
+
toolName: "asset_put",
|
|
207
|
+
args: { path: "/tmp/output.png" },
|
|
208
|
+
result: {
|
|
209
|
+
ok: true,
|
|
210
|
+
asset: {
|
|
211
|
+
uri: "asset://store/2026/03/27/asset_1",
|
|
212
|
+
name: "output.png",
|
|
213
|
+
mimeType: "image/png",
|
|
214
|
+
url: "/api/ncp/assets/content?uri=asset%3A%2F%2Fstore%2F2026%2F03%2F27%2Fasset_1",
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
},
|
|
221
|
+
] as unknown as ChatMessageSource[]);
|
|
222
|
+
|
|
223
|
+
expect(adapted[0]?.parts[0]).toEqual({
|
|
224
|
+
type: "file",
|
|
225
|
+
file: {
|
|
226
|
+
label: "output.png",
|
|
227
|
+
mimeType: "image/png",
|
|
228
|
+
dataUrl: "/api/ncp/assets/content?uri=asset%3A%2F%2Fstore%2F2026%2F03%2F27%2Fasset_1",
|
|
229
|
+
isImage: true,
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
});
|
|
@@ -76,6 +76,58 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|
|
76
76
|
return typeof value === 'object' && value !== null;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
function readOptionalString(value: unknown): string | null {
|
|
80
|
+
if (typeof value !== 'string') {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
const trimmed = value.trim();
|
|
84
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function extractAssetFileView(
|
|
88
|
+
value: unknown,
|
|
89
|
+
texts: ChatMessageAdapterTexts
|
|
90
|
+
):
|
|
91
|
+
| {
|
|
92
|
+
type: 'file';
|
|
93
|
+
file: {
|
|
94
|
+
label: string;
|
|
95
|
+
mimeType: string;
|
|
96
|
+
dataUrl: string;
|
|
97
|
+
isImage: boolean;
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
| null {
|
|
101
|
+
if (!isRecord(value)) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
const assetCandidate = isRecord(value.asset)
|
|
105
|
+
? value.asset
|
|
106
|
+
: Array.isArray(value.assets) && value.assets.length > 0 && isRecord(value.assets[0])
|
|
107
|
+
? value.assets[0]
|
|
108
|
+
: null;
|
|
109
|
+
if (!assetCandidate) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
const url = readOptionalString(assetCandidate.url);
|
|
113
|
+
const mimeType = readOptionalString(assetCandidate.mimeType) ?? 'application/octet-stream';
|
|
114
|
+
if (!url) {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
const label =
|
|
118
|
+
readOptionalString(assetCandidate.name) ??
|
|
119
|
+
(mimeType.startsWith('image/') ? texts.imageAttachmentLabel : texts.fileAttachmentLabel);
|
|
120
|
+
return {
|
|
121
|
+
type: 'file',
|
|
122
|
+
file: {
|
|
123
|
+
label,
|
|
124
|
+
mimeType,
|
|
125
|
+
dataUrl: url,
|
|
126
|
+
isImage: mimeType.startsWith('image/')
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
79
131
|
function isTextPart(part: ChatMessagePartSource): part is Extract<ChatMessagePartSource, { type: 'text' }> {
|
|
80
132
|
return part.type === 'text' && typeof part.text === 'string';
|
|
81
133
|
}
|
|
@@ -223,6 +275,10 @@ export function adaptChatMessages(params: {
|
|
|
223
275
|
}
|
|
224
276
|
if (isToolInvocationPart(part)) {
|
|
225
277
|
const invocation = part.toolInvocation;
|
|
278
|
+
const assetFileView = extractAssetFileView(invocation.result, params.texts);
|
|
279
|
+
if (assetFileView) {
|
|
280
|
+
return assetFileView;
|
|
281
|
+
}
|
|
226
282
|
const detail = summarizeToolArgs(invocation.parsedArgs ?? invocation.args);
|
|
227
283
|
const rawResult =
|
|
228
284
|
typeof invocation.error === 'string' && invocation.error.trim()
|
|
@@ -87,8 +87,8 @@ describe('deriveNcpMessagePartsFromComposer', () => {
|
|
|
87
87
|
name: 'config.json',
|
|
88
88
|
mimeType: 'application/json',
|
|
89
89
|
sizeBytes: 18,
|
|
90
|
-
|
|
91
|
-
url: '/api/ncp/
|
|
90
|
+
assetUri: 'asset://store/2026/03/26/asset_123',
|
|
91
|
+
url: '/api/ncp/assets/content?uri=asset%3A%2F%2Fstore%2F2026%2F03%2F26%2Fasset_123'
|
|
92
92
|
}
|
|
93
93
|
]
|
|
94
94
|
);
|
|
@@ -98,8 +98,8 @@ describe('deriveNcpMessagePartsFromComposer', () => {
|
|
|
98
98
|
type: 'file',
|
|
99
99
|
name: 'config.json',
|
|
100
100
|
mimeType: 'application/json',
|
|
101
|
-
|
|
102
|
-
url: '/api/ncp/
|
|
101
|
+
assetUri: 'asset://store/2026/03/26/asset_123',
|
|
102
|
+
url: '/api/ncp/assets/content?uri=asset%3A%2F%2Fstore%2F2026%2F03%2F26%2Fasset_123',
|
|
103
103
|
sizeBytes: 18
|
|
104
104
|
}
|
|
105
105
|
]);
|
|
@@ -108,7 +108,7 @@ export function deriveNcpMessagePartsFromComposer(
|
|
|
108
108
|
type: 'file',
|
|
109
109
|
name: attachment.name,
|
|
110
110
|
mimeType: attachment.mimeType,
|
|
111
|
-
...(attachment.
|
|
111
|
+
...(attachment.assetUri ? { assetUri: attachment.assetUri } : {}),
|
|
112
112
|
...(attachment.url ? { url: attachment.url } : {}),
|
|
113
113
|
...(attachment.contentBase64 ? { contentBase64: attachment.contentBase64 } : {}),
|
|
114
114
|
sizeBytes: attachment.sizeBytes
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
DEFAULT_NCP_ATTACHMENT_MAX_BYTES,
|
|
5
5
|
uploadFilesAsNcpDraftAttachments
|
|
6
6
|
} from '@nextclaw/ncp-react';
|
|
7
|
-
import {
|
|
7
|
+
import { uploadNcpAssets } from '@/api/ncp-attachments';
|
|
8
8
|
import {
|
|
9
9
|
buildChatSlashItems,
|
|
10
10
|
buildModelStateHint,
|
|
@@ -150,7 +150,7 @@ export function ChatInputBarContainer() {
|
|
|
150
150
|
return;
|
|
151
151
|
}
|
|
152
152
|
const result = await uploadFilesAsNcpDraftAttachments(files, {
|
|
153
|
-
uploadBatch:
|
|
153
|
+
uploadBatch: uploadNcpAssets,
|
|
154
154
|
});
|
|
155
155
|
if (result.attachments.length > 0) {
|
|
156
156
|
const insertedAttachments = presenter.chatInputManager.addAttachments?.(result.attachments) ?? [];
|