@castlekit/castle 0.4.1 → 0.4.3
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/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +2 -2
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/server/app/_global-error.html +2 -2
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/chat.html +1 -1
- package/.next/standalone/.next/server/app/chat.rsc +1 -1
- package/.next/standalone/.next/server/app/chat.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/chat.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/chat.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/chat.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/chat.segments/chat/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/chat.segments/chat.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings.html +1 -1
- package/.next/standalone/.next/server/app/settings.rsc +1 -1
- package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings.segments/settings.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/ui-kit.html +1 -1
- package/.next/standalone/.next/server/app/ui-kit.rsc +1 -1
- package/.next/standalone/.next/server/app/ui-kit.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/ui-kit.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/ui-kit.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/ui-kit.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/ui-kit.segments/ui-kit/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/ui-kit.segments/ui-kit.segment.rsc +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__2824c41d._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__361bce14._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_7a67de23._.js +1 -1
- package/.next/standalone/.next/server/middleware-manifest.json +5 -5
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +2 -2
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/{static/chunks/2b48886a383c2e37.js → standalone/.next/static/chunks/8c691cfaccdbb9ee.js} +1 -1
- package/.next/standalone/CHANGELOG.md +26 -0
- package/.next/standalone/bin/castle.js +2 -2
- package/.next/standalone/install.ps1 +16 -16
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/src/app/api/openclaw/agents/[id]/avatar/route.ts +51 -91
- package/.next/standalone/src/app/api/openclaw/agents/route.ts +12 -0
- package/.next/standalone/src/app/page.tsx +3 -3
- package/.next/standalone/src/cli/onboarding.ts +90 -87
- package/.next/{standalone/.next/static/chunks/2b48886a383c2e37.js → static/chunks/8c691cfaccdbb9ee.js} +1 -1
- package/bin/castle.js +2 -2
- package/install.ps1 +16 -16
- package/package.json +1 -1
- package/src/app/api/openclaw/agents/[id]/avatar/route.ts +51 -91
- package/src/app/api/openclaw/agents/route.ts +12 -0
- package/src/app/page.tsx +3 -3
- package/src/cli/onboarding.ts +90 -87
- /package/.next/standalone/.next/static/{IDGX3MGCjqUE6NQVlug5A → PzpTWZTNAsAIh96H48auo}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{IDGX3MGCjqUE6NQVlug5A → PzpTWZTNAsAIh96H48auo}/_clientMiddlewareManifest.json +0 -0
- /package/.next/standalone/.next/static/{IDGX3MGCjqUE6NQVlug5A → PzpTWZTNAsAIh96H48auo}/_ssgManifest.js +0 -0
- /package/.next/static/{IDGX3MGCjqUE6NQVlug5A → PzpTWZTNAsAIh96H48auo}/_buildManifest.js +0 -0
- /package/.next/static/{IDGX3MGCjqUE6NQVlug5A → PzpTWZTNAsAIh96H48auo}/_clientMiddlewareManifest.json +0 -0
- /package/.next/static/{IDGX3MGCjqUE6NQVlug5A → PzpTWZTNAsAIh96H48auo}/_ssgManifest.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,41613,e=>{"use strict";var t=e.i(18050),a=e.i(75157);function r({title:e,subtitle:r,className:s}){return(0,t.jsxs)("div",{className:(0,a.cn)("space-y-2",s),children:[(0,t.jsx)("h1",{className:"text-2xl font-semibold text-foreground",children:e}),r?(0,t.jsx)("p",{className:"text-sm text-foreground-secondary",children:r}):null]})}e.s(["PageHeader",()=>r])},15288,87486,e=>{"use strict";var t=e.i(18050),a=e.i(71645),r=e.i(75157);let s=(0,a.forwardRef)(({className:e,variant:a="default",...s},n)=>(0,t.jsx)("div",{className:(0,r.cn)("rounded-[var(--radius-md)] bg-surface p-6",{"":"default"===a,"border border-border":"bordered"===a,"shadow-lg shadow-black/5 dark:shadow-black/20":"elevated"===a},e),ref:n,...s}));s.displayName="Card";let n=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("div",{className:(0,r.cn)("flex flex-col space-y-1.5 pb-4",e),ref:s,...a}));n.displayName="CardHeader";let i=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("h3",{className:(0,r.cn)("text-lg font-semibold leading-none tracking-tight text-foreground",e),ref:s,...a}));i.displayName="CardTitle";let l=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("p",{className:(0,r.cn)("text-sm text-foreground-secondary",e),ref:s,...a}));l.displayName="CardDescription";let o=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("div",{className:(0,r.cn)("",e),ref:s,...a}));o.displayName="CardContent";let c=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("div",{className:(0,r.cn)("flex items-center pt-4",e),ref:s,...a}));function d({className:e,variant:a="default",size:s="md",...n}){return(0,t.jsx)("span",{className:(0,r.cn)("inline-flex items-center font-medium rounded-[var(--radius-full)] transition-colors",{"bg-surface text-foreground-secondary":"default"===a,"bg-success/10 text-success":"success"===a,"bg-warning/10 text-warning":"warning"===a,"bg-error/10 text-error":"error"===a,"bg-info/10 text-info":"info"===a,"bg-transparent text-foreground-secondary border border-border":"outline"===a},{"px-2 py-0.5 text-xs":"sm"===s,"px-2.5 py-0.5 text-sm":"md"===s},e),...n})}c.displayName="CardFooter",e.s(["Card",()=>s,"CardContent",()=>o,"CardDescription",()=>l,"CardFooter",()=>c,"CardHeader",()=>n,"CardTitle",()=>i],15288),e.s(["Badge",()=>d],87486)},29143,18809,e=>{"use strict";var t=e.i(71645),a=e.i(83599);let r=null,s=0,n=-1,i=Date.now(),l=new Map,o=new Set;function c(e,t){return l.has(e)||l.set(e,new Set),l.get(e).add(t),1==++s&&(r||(console.log("[SSE Client] Opening connection (subscribers:",s+")"),r=new EventSource("/api/openclaw/events"),i=Date.now(),r.onopen=()=>{console.log("[SSE Client] Connected")},r.onmessage=e=>{try{let t=JSON.parse(e.data);!function(e){if(i=Date.now(),"number"==typeof e.seq){if(e.seq<=n)return console.debug("[SSE Client] Dropped duplicate event seq:",e.seq,"event:",e.event);n=e.seq}let t=e.event;for(let[a,r]of l)if("*"===a||(a.endsWith(".*")?t.startsWith(a.slice(0,-1)):t===a))for(let t of r)try{t(e)}catch(e){console.error("[SSE] Handler error:",e)}}(t)}catch(t){console.warn("[SSE Client] Failed to parse event:",t.message,"data:",e.data?.slice(0,100))}},r.onerror=e=>{for(let e of(console.warn("[SSE Client] Connection error (readyState:",r?.readyState+")"),o))try{e()}catch{}})),()=>{let a=l.get(e);a&&(a.delete(t),0===a.size&&l.delete(e)),--s<=0&&(s=0,r&&(console.log("[SSE Client] Closing connection"),r.close(),r=null),n=-1)}}function d(e){return o.add(e),()=>{o.delete(e)}}function u(){return i}e.s(["getLastEventTimestamp",()=>u,"onError",()=>d,"subscribe",()=>c],18809);let h=async e=>{let t=await fetch(e,{method:"POST"});return t.ok||console.warn(`[useOpenClaw] Status fetch returned ${t.status}`),t.json()},x=async e=>{let t=await fetch(e);return t.ok?(await t.json()).agents||[]:(console.warn(`[useOpenClaw] Agents fetch failed: ${t.status}`),[])};function f(){let{data:e,error:r,isLoading:s,mutate:n}=(0,a.default)("/api/openclaw/ping",h,{refreshInterval:6e4,revalidateOnFocus:!0,dedupingInterval:1e4,errorRetryCount:2}),i=e?.ok??!1,{data:l,isLoading:o,mutate:u}=(0,a.default)(i?"/api/openclaw/agents":null,x,{refreshInterval:3e5,revalidateOnFocus:!1,dedupingInterval:3e4}),f=(0,t.useCallback)(async()=>{await n(),i&&await u()},[n,u,i]),m=(0,t.useCallback)(()=>u(),[u]);return(0,t.useEffect)(()=>{let e=e=>{u()},t=c("castle.state",e=>{let t=e.payload;n(e=>({ok:t.isConnected,configured:e?.configured??!0,state:t.state,server:t.server}),{revalidate:!1}),t.isConnected&&u()}),a=c("agent.*",e),r=c("agentAvatarUpdated",e),s=d(()=>{console.warn("[useOpenClaw] SSE error — marking as disconnected"),n(e=>e?{...e,ok:!1,state:"disconnected"}:e,{revalidate:!1})});return()=>{t(),a(),r(),s()}},[n,u]),{status:e,isLoading:s,isError:!!r,isConnected:i,isConfigured:e?.configured??!1,latency:e?.latency_ms,serverVersion:e?.server?.version,agents:l??[],agentsLoading:o,refresh:f,refreshAgents:m}}e.s(["useOpenClaw",()=>f],29143)},63209,e=>{"use strict";let t=(0,e.i(75254).default)("circle-alert",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]]);e.s(["AlertCircle",()=>t],63209)},31245,e=>{"use strict";let t=(0,e.i(75254).default)("bot",[["path",{d:"M12 8V4H8",key:"hb8ula"}],["rect",{width:"16",height:"12",x:"4",y:"8",rx:"2",key:"enze0r"}],["path",{d:"M2 14h2",key:"vft8re"}],["path",{d:"M20 14h2",key:"4cs60a"}],["path",{d:"M15 13v2",key:"1xurst"}],["path",{d:"M9 13v2",key:"rq6x2g"}]]);e.s(["Bot",()=>t],31245)},57212,e=>{"use strict";let t=(0,e.i(75254).default)("wifi-off",[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}],["path",{d:"M5 12.859a10 10 0 0 1 5.17-2.69",key:"1dl1wf"}],["path",{d:"M19 12.859a10 10 0 0 0-2.007-1.523",key:"4k23kn"}],["path",{d:"M2 8.82a15 15 0 0 1 4.177-2.643",key:"1grhjp"}],["path",{d:"M22 8.82a15 15 0 0 0-11.288-3.764",key:"z3jwby"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]]);e.s(["WifiOff",()=>t],57212)},16715,e=>{"use strict";let t=(0,e.i(75254).default)("refresh-cw",[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]]);e.s(["RefreshCw",()=>t],16715)},31278,e=>{"use strict";let t=(0,e.i(75254).default)("loader-circle",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);e.s(["Loader2",()=>t],31278)},94983,e=>{"use strict";let t=(0,e.i(75254).default)("message-circle",[["path",{d:"M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719",key:"1sd12s"}]]);e.s(["MessageCircle",()=>t],94983)},84614,e=>{"use strict";let t=(0,e.i(75254).default)("user",[["path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",key:"975kel"}],["circle",{cx:"12",cy:"7",r:"4",key:"17ys0d"}]]);e.s(["User",()=>t],84614)},46798,e=>{"use strict";var t=e.i(18050),a=e.i(71645),r=e.i(74080),s=e.i(75157);function n({children:e,content:n,side:i="right",className:l,delay:o=0}){let[c,d]=(0,a.useState)(!1),[u,h]=(0,a.useState)(!1),x=(0,a.useRef)(null),[f,m]=(0,a.useState)({x:0,y:0}),[p,g]=(0,a.useState)(!1),v=(0,a.useRef)(null),b=(0,a.useRef)(null);(0,a.useEffect)(()=>(h(!0),()=>{x.current&&clearTimeout(x.current)}),[]);let y=(0,a.useCallback)(()=>{if(v.current&&b.current){let e=v.current.getBoundingClientRect(),t=b.current.getBoundingClientRect(),a=0,r=0;switch(i){case"top":a=e.left+e.width/2-t.width/2,r=e.top-t.height-10;break;case"bottom":a=e.left+e.width/2-t.width/2,r=e.bottom+10;break;case"left":a=e.left-t.width-10,r=e.top+e.height/2-t.height/2;break;default:a=e.right+10,r=e.top+e.height/2-t.height/2}m({x:a,y:r}),g(!0)}},[i]);return(0,a.useLayoutEffect)(()=>{if(!c)return void g(!1);y();let e=()=>y();return window.addEventListener("resize",e),window.addEventListener("scroll",e,!0),()=>{window.removeEventListener("resize",e),window.removeEventListener("scroll",e,!0)}},[c,y]),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("div",{ref:v,onMouseEnter:()=>{o>0?x.current=setTimeout(()=>d(!0),o):d(!0)},onMouseLeave:()=>{x.current&&(clearTimeout(x.current),x.current=null),d(!1)},className:l,children:e}),c&&u?(0,r.createPortal)((0,t.jsx)("div",{ref:b,className:"fixed z-[9999] pointer-events-none",style:{left:f.x,top:f.y,visibility:p?"visible":"hidden"},children:(0,t.jsx)("div",{className:(0,s.cn)("transition-all duration-150 ease-out",p?"opacity-100 scale-100":"opacity-0 scale-95","right"===i&&(p?"translate-x-0":"-translate-x-2"),"left"===i&&(p?"translate-x-0":"translate-x-2"),"top"===i&&(p?"translate-y-0":"translate-y-2"),"bottom"===i&&(p?"translate-y-0":"-translate-y-2")),children:(0,t.jsxs)("div",{className:"relative bg-[#1a1a1a] text-white text-sm font-medium px-3 py-1.5 rounded-[4px] whitespace-nowrap shadow-xl shadow-black/25",children:[n,"right"===i&&(0,t.jsx)("div",{className:"absolute -left-[7px] top-1/2 -translate-y-1/2",children:(0,t.jsx)("div",{className:"w-0 h-0 border-t-[8px] border-t-transparent border-b-[8px] border-b-transparent border-r-[8px] border-r-[#1a1a1a]"})}),"left"===i&&(0,t.jsx)("div",{className:"absolute -right-[7px] top-1/2 -translate-y-1/2",children:(0,t.jsx)("div",{className:"w-0 h-0 border-t-[8px] border-t-transparent border-b-[8px] border-b-transparent border-l-[8px] border-l-[#1a1a1a]"})}),"top"===i&&(0,t.jsx)("div",{className:"absolute -bottom-[7px] left-1/2 -translate-x-1/2",children:(0,t.jsx)("div",{className:"w-0 h-0 border-l-[8px] border-l-transparent border-r-[8px] border-r-transparent border-t-[8px] border-t-[#1a1a1a]"})}),"bottom"===i&&(0,t.jsx)("div",{className:"absolute -top-[7px] left-1/2 -translate-x-1/2",children:(0,t.jsx)("div",{className:"w-0 h-0 border-l-[8px] border-l-transparent border-r-[8px] border-r-transparent border-b-[8px] border-b-[#1a1a1a]"})})]})})}),document.body):null]})}e.s(["Tooltip",()=>n])},19009,e=>{"use strict";var t=e.i(83599);let a=e=>fetch(e).then(e=>e.json());function r(){let{data:e,mutate:r,isLoading:s}=(0,t.default)("/api/settings",a,{revalidateOnFocus:!0,dedupingInterval:5e3}),n=e?.displayName||"";return{displayName:n,avatarUrl:e?.avatarPath?`/api/settings/avatar?v=${encodeURIComponent(e.avatarPath)}`:null,tooltips:e?.tooltips!=="false",isLoading:s,refresh:()=>r()}}e.s(["useUserSettings",()=>r])},99676,e=>{"use strict";var t=e.i(18050),a=e.i(71645),r=e.i(75157);let s=(0,a.forwardRef)(({className:e,size:a="md",status:s,statusPulse:n,children:i,...l},o)=>(0,t.jsxs)("div",{className:"relative inline-block shrink-0",children:[(0,t.jsx)("div",{className:(0,r.cn)("relative flex shrink-0 overflow-hidden rounded-[4px] bg-surface border border-border",{"h-9 w-9":"sm"===a,"h-10 w-10":"md"===a,"h-12 w-12":"lg"===a},e),ref:o,...l,children:i}),s&&(0,t.jsx)("span",{className:(0,r.cn)("absolute block rounded-full ring-2 ring-background",{"h-2.5 w-2.5 -bottom-0.5 -right-0.5":"sm"===a,"h-3 w-3 -bottom-0.5 -right-0.5":"md"===a,"h-3.5 w-3.5 -bottom-0.5 -right-0.5":"lg"===a},{"bg-success":"online"===s,"bg-foreground-muted":"offline"===s,"bg-error":"busy"===s,"bg-warning":"away"===s},n&&"animate-pulse")})]}));s.displayName="Avatar";let n=(0,a.forwardRef)(({className:e,alt:a,...s},n)=>(0,t.jsx)("img",{className:(0,r.cn)("aspect-square h-full w-full object-cover",e),alt:a,ref:n,...s}));n.displayName="AvatarImage";let i=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("span",{className:(0,r.cn)("flex h-full w-full items-center justify-center bg-surface text-foreground-secondary font-medium text-sm",e),ref:s,...a}));i.displayName="AvatarFallback",e.s(["Avatar",()=>s,"AvatarFallback",()=>i,"AvatarImage",()=>n])},94037,60289,97250,91799,39616,e=>{"use strict";var t=e.i(18050),a=e.i(71645),r=e.i(63178),s=e.i(75254);let n=(0,s.default)("layout-dashboard",[["rect",{width:"7",height:"9",x:"3",y:"3",rx:"1",key:"10lvy0"}],["rect",{width:"7",height:"5",x:"14",y:"3",rx:"1",key:"16une8"}],["rect",{width:"7",height:"9",x:"14",y:"12",rx:"1",key:"1hutg5"}],["rect",{width:"7",height:"5",x:"3",y:"16",rx:"1",key:"ldoo1y"}]]);e.s(["LayoutDashboard",()=>n],60289);var i=e.i(94983),l=e.i(84614);let o=(0,s.default)("sun",[["circle",{cx:"12",cy:"12",r:"4",key:"4exip2"}],["path",{d:"M12 2v2",key:"tus03m"}],["path",{d:"M12 20v2",key:"1lh1kg"}],["path",{d:"m4.93 4.93 1.41 1.41",key:"149t6j"}],["path",{d:"m17.66 17.66 1.41 1.41",key:"ptbguv"}],["path",{d:"M2 12h2",key:"1t8f8n"}],["path",{d:"M20 12h2",key:"1q8mjw"}],["path",{d:"m6.34 17.66-1.41 1.41",key:"1m8zz5"}],["path",{d:"m19.07 4.93-1.41 1.41",key:"1shlcs"}]]);e.s(["Sun",()=>o],97250);let c=(0,s.default)("moon",[["path",{d:"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401",key:"kfwtm"}]]);e.s(["Moon",()=>c],91799);let d=(0,s.default)("settings",[["path",{d:"M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915",key:"1i5ecw"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);e.s(["Settings",()=>d],39616);var u=e.i(75157);function h({className:e}){return(0,t.jsx)("svg",{viewBox:"0 0 512 512",xmlns:"http://www.w3.org/2000/svg",className:(0,u.cn)("fill-current",e),children:(0,t.jsxs)("g",{children:[(0,t.jsx)("path",{d:"m124.809 408.11h262.382v103.89h-262.382z"}),(0,t.jsx)("path",{d:"m273.162 123.55h134.646l-34.459-44.772 33.515-46.459h-133.702v-32.319h-29.985v196.446h29.985z"}),(0,t.jsx)("path",{d:"m347.45 281.985h-50.335v-56.54h-79.107v56.54h-53.643v-56.54h-91.962v111.141c0 23.448 19.075 42.523 42.523 42.523h282.147c23.448 0 42.524-19.075 42.524-42.523v-111.14h-92.147z"})]})})}var x=e.i(46798),f=e.i(18566),m=e.i(19009),p=e.i(57401),g=e.i(99676);let v=[{id:"dashboard",label:"Dashboard",icon:n,href:"/"},{id:"chat",label:"Chat",icon:i.MessageCircle,href:"/chat"}];function b({activeItem:e="dashboard",onNavigate:a,className:r,variant:s="solid"}){let n=(0,f.usePathname)(),i=(0,f.useRouter)(),l=!a,{tooltips:o}=(0,m.useUserSettings)(),c=n&&"/"!==n&&n.startsWith("/chat")?"chat":"dashboard",d=l?c:e;return(0,t.jsxs)("aside",{className:(0,u.cn)("fixed top-[20px] left-[24px] bottom-[20px] flex flex-col z-40 rounded-[var(--radius-md)] w-14","glass"===s?"glass":"bg-surface border border-border",r),children:[(0,t.jsx)("div",{className:"flex items-center justify-center pt-5 pb-[60px]",children:(0,t.jsx)("button",{type:"button","aria-label":"Go to Dashboard",onClick:()=>l?i.push("/"):a?.("dashboard"),className:"flex items-center justify-center transition-opacity hover:opacity-85 cursor-pointer",children:(0,t.jsx)(h,{className:"h-[36px] w-[36px] min-h-[36px] min-w-[36px] shrink-0 text-[var(--logo-color)] -mt-[3px]"})})}),(0,t.jsx)("nav",{className:"flex-1 space-y-1 px-2",children:v.map(e=>{let r=d===e.id,s=(0,t.jsx)("button",{onClick:()=>l?i.push(e.href):a?.(e.id),className:(0,u.cn)("flex items-center justify-center w-full rounded-[4px] p-2.5 cursor-pointer",r?"bg-accent/10 text-accent":"text-foreground-secondary hover:text-foreground hover:bg-surface-hover"),children:(0,t.jsx)(e.icon,{className:"h-5 w-5 shrink-0"})});return o?(0,t.jsx)(x.Tooltip,{content:e.label,side:"right",children:s},e.id):(0,t.jsx)("div",{children:s},e.id)})}),(0,t.jsx)(y,{})]})}function y(){let[e,s]=(0,a.useState)(!1),{theme:n,setTheme:i}=(0,r.useTheme)(),[u,h]=(0,a.useState)(!1),x=(0,f.useRouter)(),{avatarUrl:v,isLoading:b}=(0,m.useUserSettings)(),{getStatus:y}=(0,p.useAgentStatus)(),j=y(p.USER_STATUS_ID),w=(0,a.useRef)(null);(0,a.useEffect)(()=>{h(!0)},[]),(0,a.useEffect)(()=>{function e(e){w.current&&!w.current.contains(e.target)&&s(!1)}return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[]);let k="dark"===n;return(0,t.jsxs)("div",{ref:w,className:"relative flex justify-center pb-[8px]",children:[(0,t.jsx)("button",{onClick:()=>s(!e),className:"group flex items-center justify-center rounded-[4px] cursor-pointer transition-opacity",children:(0,t.jsx)(g.Avatar,{size:"sm",status:"active"===j?"online":"offline",children:b?(0,t.jsx)(g.AvatarFallback,{className:"skeleton"}):v?(0,t.jsx)(g.AvatarImage,{src:v,alt:"You",className:"grayscale group-hover:grayscale-0 transition-all duration-200"}):(0,t.jsx)(g.AvatarFallback,{className:"text-foreground-secondary",children:(0,t.jsx)(l.User,{className:"h-5 w-5"})})})}),e&&(0,t.jsxs)("div",{className:"absolute left-[calc(100%+8px)] bottom-0 w-48 rounded-[var(--radius-md)] bg-surface border border-border shadow-xl py-1 z-50",children:[(0,t.jsxs)("button",{onClick:()=>{s(!1),x.push("/settings")},className:"flex items-center gap-3 w-full px-4 py-2.5 text-sm text-foreground-secondary hover:text-foreground hover:bg-surface-hover cursor-pointer",children:[(0,t.jsx)(d,{className:"h-4 w-4"}),"Settings"]}),u&&(0,t.jsxs)("button",{onClick:()=>{i(k?"light":"dark"),s(!1)},className:"flex items-center gap-3 w-full px-4 py-2.5 text-sm text-foreground-secondary hover:text-foreground hover:bg-surface-hover cursor-pointer",children:[k?(0,t.jsx)(o,{className:"h-4 w-4"}):(0,t.jsx)(c,{className:"h-4 w-4"}),k?"Light mode":"Dark mode"]})]})]})}e.s(["Sidebar",()=>b],94037)},68553,e=>{"use strict";let t=(0,e.i(75254).default)("camera",[["path",{d:"M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z",key:"18u6gg"}],["circle",{cx:"12",cy:"13",r:"3",key:"1vg3eu"}]]);e.s(["Camera",()=>t],68553)},52683,e=>{"use strict";var t=e.i(18050),a=e.i(71645),r=e.i(31245),s=e.i(75254);let n=(0,s.default)("wifi",[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M2 8.82a15 15 0 0 1 20 0",key:"dnpr2z"}],["path",{d:"M5 12.859a10 10 0 0 1 14 0",key:"1x1e6c"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}]]);var i=e.i(57212);let l=(0,s.default)("crown",[["path",{d:"M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z",key:"1vdc57"}],["path",{d:"M5 21h14",key:"11awu3"}]]);var o=e.i(16715),c=e.i(31278),d=e.i(63209),u=e.i(68553),h=e.i(94037),x=e.i(41613),f=e.i(15288),m=e.i(87486),p=e.i(99676),g=e.i(75157),v=e.i(29143),b=e.i(57401),y=e.i(40871);function j({agent:e,isPrimary:r,isConnected:s,onAvatarUpdated:n}){let i=(0,a.useRef)(null),[o,d]=(0,a.useState)(!1),{getStatus:h}=(0,b.useAgentStatus)(),x=h(e.id),v=(0,a.useCallback)(()=>{s&&i.current?.click()},[s]),y=(0,a.useCallback)(async t=>{let a=t.target.files?.[0];if(a){if(t.target.value="",a.size>5242880)return void alert("Image too large (max 5MB)");d(!0);try{let t=new FormData;t.append("avatar",a);let r=await fetch(`/api/openclaw/agents/${e.id}/avatar`,{method:"POST",body:t}),s=await r.json();if(!r.ok)return void alert(s.error||"Failed to update avatar");n()}catch{alert("Failed to upload avatar")}finally{d(!1)}}},[e.id,n]);return(0,t.jsx)(f.Card,{variant:"bordered",className:(0,g.cn)("py-4 pl-5 pr-4 transition-colors min-h-[80px] flex items-center",s?"hover:border-border-hover":"opacity-60"),children:(0,t.jsxs)("div",{className:"flex items-center justify-between flex-1",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsxs)("button",{type:"button",onClick:v,disabled:!s||o,className:"relative group rounded-[4px] focus:outline-none focus-visible:ring-2 focus-visible:ring-accent leading-[0]",title:s?"Click to change avatar":void 0,children:[(0,t.jsx)(p.Avatar,{size:"md",status:function(e,t){if(!t)return"offline";switch(e){case"thinking":return"away";case"active":return"online";default:return"offline"}}(x,s),statusPulse:"thinking"===x,children:e.avatar?(0,t.jsx)(p.AvatarImage,{src:e.avatar,alt:e.name,className:(0,g.cn)(!s&&"grayscale")}):(0,t.jsx)(p.AvatarFallback,{children:e.emoji||e.name.slice(0,2).toUpperCase()})}),s&&!o&&(0,t.jsx)("div",{className:"absolute inset-0 rounded-[4px] bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center",children:(0,t.jsx)(u.Camera,{className:"h-4 w-4 text-white"})}),o&&(0,t.jsx)("div",{className:"absolute inset-0 rounded-[4px] bg-black/50 flex items-center justify-center",children:(0,t.jsx)(c.Loader2,{className:"h-4 w-4 text-white animate-spin"})})]}),(0,t.jsx)("input",{ref:i,type:"file",accept:"image/png,image/jpeg,image/webp,image/gif",className:"hidden",onChange:y}),(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:e.name}),r&&(0,t.jsxs)("span",{className:"flex items-center gap-1 text-xs text-accent",children:[(0,t.jsx)(l,{className:"h-3 w-3"}),"Primary"]})]}),(0,t.jsx)("p",{className:"text-xs text-foreground-muted",children:s?e.description||"OpenClaw Agent":"Unreachable"})]})]}),(0,t.jsx)(m.Badge,{variant:function(e,t){if(!t)return"outline";switch(e){case"thinking":return"warning";case"active":return"success";default:return"outline"}}(x,s),size:"sm",children:function(e,t){if(!t)return"Offline";switch(e){case"thinking":return"Thinking";case"active":return"Active";default:return"Idle"}}(x,s)})]})})}function w({isConnected:e,isLoading:a,isConfigured:r,serverVersion:s,latency:l,error:d,onRefresh:u}){return(0,t.jsx)(f.Card,{variant:"bordered",className:"mb-8",children:(0,t.jsxs)(f.CardContent,{className:"flex items-center justify-between",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[a?(0,t.jsx)(c.Loader2,{className:"h-5 w-5 text-foreground-muted animate-spin"}):e?(0,t.jsx)(n,{className:"h-5 w-5 text-success"}):(0,t.jsx)(i.WifiOff,{className:"h-5 w-5 text-error"}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:"OpenClaw Gateway"}),(0,t.jsx)("p",{className:"text-xs text-foreground-muted",children:(()=>{if(a)return"Connecting to Gateway...";if(!r)return"Run 'castle setup' to configure";if(e){let e=["Connected"];return s&&(e[0]=`Connected to OpenClaw ${s}`),l&&e.push(`${l}ms`),e.join(" · ")}return d||"Not connected"})()})]})]}),(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("button",{onClick:u,className:"p-1.5 rounded-md text-foreground-muted hover:text-foreground hover:bg-surface-hover transition-colors",title:"Refresh connection",children:(0,t.jsx)(o.RefreshCw,{className:"h-4 w-4"})}),a?(0,t.jsx)(m.Badge,{variant:"outline",children:"Connecting..."}):(0,t.jsx)(m.Badge,{variant:e?"success":"error",children:e?"Connected":"Disconnected"})]})]})})}function k(){return(0,t.jsx)("div",{className:"grid gap-3",children:[1,2,3].map(e=>(0,t.jsx)(f.Card,{variant:"bordered",className:"p-4 min-h-[80px] flex items-center",children:(0,t.jsxs)("div",{className:"flex items-center justify-between flex-1",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsx)("div",{className:"skeleton h-10 w-10 rounded-full"}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("div",{className:"skeleton h-4 w-24 rounded"}),(0,t.jsx)("div",{className:"skeleton h-3 w-32 rounded"})]})]}),(0,t.jsx)("div",{className:"skeleton h-5 w-14 rounded-full"})]})},e))})}function N({isConfigured:e}){return(0,t.jsx)(f.Card,{variant:"bordered",className:"p-8",children:(0,t.jsx)("div",{className:"flex flex-col items-center text-center gap-3",children:e?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(d.AlertCircle,{className:"h-8 w-8 text-foreground-muted"}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:"No agents discovered"}),(0,t.jsx)("p",{className:"text-xs text-foreground-muted mt-1",children:"Make sure OpenClaw Gateway is running and agents are configured."})]})]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.Bot,{className:"h-8 w-8 text-foreground-muted"}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:"Welcome to Castle"}),(0,t.jsxs)("p",{className:"text-xs text-foreground-muted mt-1",children:["Run ",(0,t.jsx)("code",{className:"px-1 py-0.5 bg-surface-hover rounded text-xs",children:"castle setup"})," to connect to your OpenClaw Gateway."]})]})]})})})}function C(){let{status:e,isLoading:a,isConnected:s,isConfigured:n,latency:i,serverVersion:l,agents:o,agentsLoading:c,refresh:d}=(0,v.useOpenClaw)();return(0,t.jsxs)("div",{className:"min-h-screen bg-background",children:[(0,t.jsx)(h.Sidebar,{variant:"solid"}),(0,t.jsxs)("main",{className:"min-h-screen ml-[80px]",children:[(0,t.jsxs)("div",{className:"px-8 py-5 flex items-center justify-between gap-4 border-b border-border",children:[(0,t.jsx)(x.PageHeader,{title:"Castle",subtitle:"The multi-agent workspace"}),(0,t.jsx)(y.SearchTrigger,{})]}),(0,t.jsxs)("div",{className:"p-8 max-w-4xl",children:[(0,t.jsx)(w,{isConnected:s,isLoading:a,isConfigured:n,serverVersion:l,latency:i,error:e?.error,onRefresh:d}),(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between",children:[(0,t.jsxs)("h2",{className:"text-lg font-semibold text-foreground flex items-center gap-2",children:[(0,t.jsx)(r.Bot,{className:"h-5 w-5 text-foreground-secondary"}),"Agents"]}),!a&&o.length>0&&(0,t.jsxs)("span",{className:"text-sm text-foreground-muted",children:[o.length," agent",1!==o.length?"s":""," discovered"]})]}),c||a&&0===o.length?(0,t.jsx)(k,{}):o.length>0?(0,t.jsx)("div",{className:"grid gap-3",children:o.map((e,a)=>(0,t.jsx)(j,{agent:e,isPrimary:0===a,isConnected:s,onAvatarUpdated:d},e.id))}):(0,t.jsx)(N,{isConfigured:n})]})]})]})]})}e.s(["default",()=>C],52683)}]);
|
|
1
|
+
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,41613,e=>{"use strict";var t=e.i(18050),a=e.i(75157);function r({title:e,subtitle:r,className:s}){return(0,t.jsxs)("div",{className:(0,a.cn)("space-y-2",s),children:[(0,t.jsx)("h1",{className:"text-2xl font-semibold text-foreground",children:e}),r?(0,t.jsx)("p",{className:"text-sm text-foreground-secondary",children:r}):null]})}e.s(["PageHeader",()=>r])},15288,87486,e=>{"use strict";var t=e.i(18050),a=e.i(71645),r=e.i(75157);let s=(0,a.forwardRef)(({className:e,variant:a="default",...s},n)=>(0,t.jsx)("div",{className:(0,r.cn)("rounded-[var(--radius-md)] bg-surface p-6",{"":"default"===a,"border border-border":"bordered"===a,"shadow-lg shadow-black/5 dark:shadow-black/20":"elevated"===a},e),ref:n,...s}));s.displayName="Card";let n=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("div",{className:(0,r.cn)("flex flex-col space-y-1.5 pb-4",e),ref:s,...a}));n.displayName="CardHeader";let i=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("h3",{className:(0,r.cn)("text-lg font-semibold leading-none tracking-tight text-foreground",e),ref:s,...a}));i.displayName="CardTitle";let l=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("p",{className:(0,r.cn)("text-sm text-foreground-secondary",e),ref:s,...a}));l.displayName="CardDescription";let o=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("div",{className:(0,r.cn)("",e),ref:s,...a}));o.displayName="CardContent";let c=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("div",{className:(0,r.cn)("flex items-center pt-4",e),ref:s,...a}));function d({className:e,variant:a="default",size:s="md",...n}){return(0,t.jsx)("span",{className:(0,r.cn)("inline-flex items-center font-medium rounded-[var(--radius-full)] transition-colors",{"bg-surface text-foreground-secondary":"default"===a,"bg-success/10 text-success":"success"===a,"bg-warning/10 text-warning":"warning"===a,"bg-error/10 text-error":"error"===a,"bg-info/10 text-info":"info"===a,"bg-transparent text-foreground-secondary border border-border":"outline"===a},{"px-2 py-0.5 text-xs":"sm"===s,"px-2.5 py-0.5 text-sm":"md"===s},e),...n})}c.displayName="CardFooter",e.s(["Card",()=>s,"CardContent",()=>o,"CardDescription",()=>l,"CardFooter",()=>c,"CardHeader",()=>n,"CardTitle",()=>i],15288),e.s(["Badge",()=>d],87486)},29143,18809,e=>{"use strict";var t=e.i(71645),a=e.i(83599);let r=null,s=0,n=-1,i=Date.now(),l=new Map,o=new Set;function c(e,t){return l.has(e)||l.set(e,new Set),l.get(e).add(t),1==++s&&(r||(console.log("[SSE Client] Opening connection (subscribers:",s+")"),r=new EventSource("/api/openclaw/events"),i=Date.now(),r.onopen=()=>{console.log("[SSE Client] Connected")},r.onmessage=e=>{try{let t=JSON.parse(e.data);!function(e){if(i=Date.now(),"number"==typeof e.seq){if(e.seq<=n)return console.debug("[SSE Client] Dropped duplicate event seq:",e.seq,"event:",e.event);n=e.seq}let t=e.event;for(let[a,r]of l)if("*"===a||(a.endsWith(".*")?t.startsWith(a.slice(0,-1)):t===a))for(let t of r)try{t(e)}catch(e){console.error("[SSE] Handler error:",e)}}(t)}catch(t){console.warn("[SSE Client] Failed to parse event:",t.message,"data:",e.data?.slice(0,100))}},r.onerror=e=>{for(let e of(console.warn("[SSE Client] Connection error (readyState:",r?.readyState+")"),o))try{e()}catch{}})),()=>{let a=l.get(e);a&&(a.delete(t),0===a.size&&l.delete(e)),--s<=0&&(s=0,r&&(console.log("[SSE Client] Closing connection"),r.close(),r=null),n=-1)}}function d(e){return o.add(e),()=>{o.delete(e)}}function u(){return i}e.s(["getLastEventTimestamp",()=>u,"onError",()=>d,"subscribe",()=>c],18809);let h=async e=>{let t=await fetch(e,{method:"POST"});return t.ok||console.warn(`[useOpenClaw] Status fetch returned ${t.status}`),t.json()},x=async e=>{let t=await fetch(e);return t.ok?(await t.json()).agents||[]:(console.warn(`[useOpenClaw] Agents fetch failed: ${t.status}`),[])};function f(){let{data:e,error:r,isLoading:s,mutate:n}=(0,a.default)("/api/openclaw/ping",h,{refreshInterval:6e4,revalidateOnFocus:!0,dedupingInterval:1e4,errorRetryCount:2}),i=e?.ok??!1,{data:l,isLoading:o,mutate:u}=(0,a.default)(i?"/api/openclaw/agents":null,x,{refreshInterval:3e5,revalidateOnFocus:!1,dedupingInterval:3e4}),f=(0,t.useCallback)(async()=>{await n(),i&&await u()},[n,u,i]),m=(0,t.useCallback)(()=>u(),[u]);return(0,t.useEffect)(()=>{let e=e=>{u()},t=c("castle.state",e=>{let t=e.payload;n(e=>({ok:t.isConnected,configured:e?.configured??!0,state:t.state,server:t.server}),{revalidate:!1}),t.isConnected&&u()}),a=c("agent.*",e),r=c("agentAvatarUpdated",e),s=d(()=>{console.warn("[useOpenClaw] SSE error — marking as disconnected"),n(e=>e?{...e,ok:!1,state:"disconnected"}:e,{revalidate:!1})});return()=>{t(),a(),r(),s()}},[n,u]),{status:e,isLoading:s,isError:!!r,isConnected:i,isConfigured:e?.configured??!1,latency:e?.latency_ms,serverVersion:e?.server?.version,agents:l??[],agentsLoading:o,refresh:f,refreshAgents:m}}e.s(["useOpenClaw",()=>f],29143)},63209,e=>{"use strict";let t=(0,e.i(75254).default)("circle-alert",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]]);e.s(["AlertCircle",()=>t],63209)},31245,e=>{"use strict";let t=(0,e.i(75254).default)("bot",[["path",{d:"M12 8V4H8",key:"hb8ula"}],["rect",{width:"16",height:"12",x:"4",y:"8",rx:"2",key:"enze0r"}],["path",{d:"M2 14h2",key:"vft8re"}],["path",{d:"M20 14h2",key:"4cs60a"}],["path",{d:"M15 13v2",key:"1xurst"}],["path",{d:"M9 13v2",key:"rq6x2g"}]]);e.s(["Bot",()=>t],31245)},57212,e=>{"use strict";let t=(0,e.i(75254).default)("wifi-off",[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}],["path",{d:"M5 12.859a10 10 0 0 1 5.17-2.69",key:"1dl1wf"}],["path",{d:"M19 12.859a10 10 0 0 0-2.007-1.523",key:"4k23kn"}],["path",{d:"M2 8.82a15 15 0 0 1 4.177-2.643",key:"1grhjp"}],["path",{d:"M22 8.82a15 15 0 0 0-11.288-3.764",key:"z3jwby"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]]);e.s(["WifiOff",()=>t],57212)},16715,e=>{"use strict";let t=(0,e.i(75254).default)("refresh-cw",[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]]);e.s(["RefreshCw",()=>t],16715)},31278,e=>{"use strict";let t=(0,e.i(75254).default)("loader-circle",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);e.s(["Loader2",()=>t],31278)},94983,e=>{"use strict";let t=(0,e.i(75254).default)("message-circle",[["path",{d:"M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719",key:"1sd12s"}]]);e.s(["MessageCircle",()=>t],94983)},84614,e=>{"use strict";let t=(0,e.i(75254).default)("user",[["path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",key:"975kel"}],["circle",{cx:"12",cy:"7",r:"4",key:"17ys0d"}]]);e.s(["User",()=>t],84614)},46798,e=>{"use strict";var t=e.i(18050),a=e.i(71645),r=e.i(74080),s=e.i(75157);function n({children:e,content:n,side:i="right",className:l,delay:o=0}){let[c,d]=(0,a.useState)(!1),[u,h]=(0,a.useState)(!1),x=(0,a.useRef)(null),[f,m]=(0,a.useState)({x:0,y:0}),[p,g]=(0,a.useState)(!1),v=(0,a.useRef)(null),b=(0,a.useRef)(null);(0,a.useEffect)(()=>(h(!0),()=>{x.current&&clearTimeout(x.current)}),[]);let y=(0,a.useCallback)(()=>{if(v.current&&b.current){let e=v.current.getBoundingClientRect(),t=b.current.getBoundingClientRect(),a=0,r=0;switch(i){case"top":a=e.left+e.width/2-t.width/2,r=e.top-t.height-10;break;case"bottom":a=e.left+e.width/2-t.width/2,r=e.bottom+10;break;case"left":a=e.left-t.width-10,r=e.top+e.height/2-t.height/2;break;default:a=e.right+10,r=e.top+e.height/2-t.height/2}m({x:a,y:r}),g(!0)}},[i]);return(0,a.useLayoutEffect)(()=>{if(!c)return void g(!1);y();let e=()=>y();return window.addEventListener("resize",e),window.addEventListener("scroll",e,!0),()=>{window.removeEventListener("resize",e),window.removeEventListener("scroll",e,!0)}},[c,y]),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("div",{ref:v,onMouseEnter:()=>{o>0?x.current=setTimeout(()=>d(!0),o):d(!0)},onMouseLeave:()=>{x.current&&(clearTimeout(x.current),x.current=null),d(!1)},className:l,children:e}),c&&u?(0,r.createPortal)((0,t.jsx)("div",{ref:b,className:"fixed z-[9999] pointer-events-none",style:{left:f.x,top:f.y,visibility:p?"visible":"hidden"},children:(0,t.jsx)("div",{className:(0,s.cn)("transition-all duration-150 ease-out",p?"opacity-100 scale-100":"opacity-0 scale-95","right"===i&&(p?"translate-x-0":"-translate-x-2"),"left"===i&&(p?"translate-x-0":"translate-x-2"),"top"===i&&(p?"translate-y-0":"translate-y-2"),"bottom"===i&&(p?"translate-y-0":"-translate-y-2")),children:(0,t.jsxs)("div",{className:"relative bg-[#1a1a1a] text-white text-sm font-medium px-3 py-1.5 rounded-[4px] whitespace-nowrap shadow-xl shadow-black/25",children:[n,"right"===i&&(0,t.jsx)("div",{className:"absolute -left-[7px] top-1/2 -translate-y-1/2",children:(0,t.jsx)("div",{className:"w-0 h-0 border-t-[8px] border-t-transparent border-b-[8px] border-b-transparent border-r-[8px] border-r-[#1a1a1a]"})}),"left"===i&&(0,t.jsx)("div",{className:"absolute -right-[7px] top-1/2 -translate-y-1/2",children:(0,t.jsx)("div",{className:"w-0 h-0 border-t-[8px] border-t-transparent border-b-[8px] border-b-transparent border-l-[8px] border-l-[#1a1a1a]"})}),"top"===i&&(0,t.jsx)("div",{className:"absolute -bottom-[7px] left-1/2 -translate-x-1/2",children:(0,t.jsx)("div",{className:"w-0 h-0 border-l-[8px] border-l-transparent border-r-[8px] border-r-transparent border-t-[8px] border-t-[#1a1a1a]"})}),"bottom"===i&&(0,t.jsx)("div",{className:"absolute -top-[7px] left-1/2 -translate-x-1/2",children:(0,t.jsx)("div",{className:"w-0 h-0 border-l-[8px] border-l-transparent border-r-[8px] border-r-transparent border-b-[8px] border-b-[#1a1a1a]"})})]})})}),document.body):null]})}e.s(["Tooltip",()=>n])},19009,e=>{"use strict";var t=e.i(83599);let a=e=>fetch(e).then(e=>e.json());function r(){let{data:e,mutate:r,isLoading:s}=(0,t.default)("/api/settings",a,{revalidateOnFocus:!0,dedupingInterval:5e3}),n=e?.displayName||"";return{displayName:n,avatarUrl:e?.avatarPath?`/api/settings/avatar?v=${encodeURIComponent(e.avatarPath)}`:null,tooltips:e?.tooltips!=="false",isLoading:s,refresh:()=>r()}}e.s(["useUserSettings",()=>r])},99676,e=>{"use strict";var t=e.i(18050),a=e.i(71645),r=e.i(75157);let s=(0,a.forwardRef)(({className:e,size:a="md",status:s,statusPulse:n,children:i,...l},o)=>(0,t.jsxs)("div",{className:"relative inline-block shrink-0",children:[(0,t.jsx)("div",{className:(0,r.cn)("relative flex shrink-0 overflow-hidden rounded-[4px] bg-surface border border-border",{"h-9 w-9":"sm"===a,"h-10 w-10":"md"===a,"h-12 w-12":"lg"===a},e),ref:o,...l,children:i}),s&&(0,t.jsx)("span",{className:(0,r.cn)("absolute block rounded-full ring-2 ring-background",{"h-2.5 w-2.5 -bottom-0.5 -right-0.5":"sm"===a,"h-3 w-3 -bottom-0.5 -right-0.5":"md"===a,"h-3.5 w-3.5 -bottom-0.5 -right-0.5":"lg"===a},{"bg-success":"online"===s,"bg-foreground-muted":"offline"===s,"bg-error":"busy"===s,"bg-warning":"away"===s},n&&"animate-pulse")})]}));s.displayName="Avatar";let n=(0,a.forwardRef)(({className:e,alt:a,...s},n)=>(0,t.jsx)("img",{className:(0,r.cn)("aspect-square h-full w-full object-cover",e),alt:a,ref:n,...s}));n.displayName="AvatarImage";let i=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("span",{className:(0,r.cn)("flex h-full w-full items-center justify-center bg-surface text-foreground-secondary font-medium text-sm",e),ref:s,...a}));i.displayName="AvatarFallback",e.s(["Avatar",()=>s,"AvatarFallback",()=>i,"AvatarImage",()=>n])},94037,60289,97250,91799,39616,e=>{"use strict";var t=e.i(18050),a=e.i(71645),r=e.i(63178),s=e.i(75254);let n=(0,s.default)("layout-dashboard",[["rect",{width:"7",height:"9",x:"3",y:"3",rx:"1",key:"10lvy0"}],["rect",{width:"7",height:"5",x:"14",y:"3",rx:"1",key:"16une8"}],["rect",{width:"7",height:"9",x:"14",y:"12",rx:"1",key:"1hutg5"}],["rect",{width:"7",height:"5",x:"3",y:"16",rx:"1",key:"ldoo1y"}]]);e.s(["LayoutDashboard",()=>n],60289);var i=e.i(94983),l=e.i(84614);let o=(0,s.default)("sun",[["circle",{cx:"12",cy:"12",r:"4",key:"4exip2"}],["path",{d:"M12 2v2",key:"tus03m"}],["path",{d:"M12 20v2",key:"1lh1kg"}],["path",{d:"m4.93 4.93 1.41 1.41",key:"149t6j"}],["path",{d:"m17.66 17.66 1.41 1.41",key:"ptbguv"}],["path",{d:"M2 12h2",key:"1t8f8n"}],["path",{d:"M20 12h2",key:"1q8mjw"}],["path",{d:"m6.34 17.66-1.41 1.41",key:"1m8zz5"}],["path",{d:"m19.07 4.93-1.41 1.41",key:"1shlcs"}]]);e.s(["Sun",()=>o],97250);let c=(0,s.default)("moon",[["path",{d:"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401",key:"kfwtm"}]]);e.s(["Moon",()=>c],91799);let d=(0,s.default)("settings",[["path",{d:"M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915",key:"1i5ecw"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);e.s(["Settings",()=>d],39616);var u=e.i(75157);function h({className:e}){return(0,t.jsx)("svg",{viewBox:"0 0 512 512",xmlns:"http://www.w3.org/2000/svg",className:(0,u.cn)("fill-current",e),children:(0,t.jsxs)("g",{children:[(0,t.jsx)("path",{d:"m124.809 408.11h262.382v103.89h-262.382z"}),(0,t.jsx)("path",{d:"m273.162 123.55h134.646l-34.459-44.772 33.515-46.459h-133.702v-32.319h-29.985v196.446h29.985z"}),(0,t.jsx)("path",{d:"m347.45 281.985h-50.335v-56.54h-79.107v56.54h-53.643v-56.54h-91.962v111.141c0 23.448 19.075 42.523 42.523 42.523h282.147c23.448 0 42.524-19.075 42.524-42.523v-111.14h-92.147z"})]})})}var x=e.i(46798),f=e.i(18566),m=e.i(19009),p=e.i(57401),g=e.i(99676);let v=[{id:"dashboard",label:"Dashboard",icon:n,href:"/"},{id:"chat",label:"Chat",icon:i.MessageCircle,href:"/chat"}];function b({activeItem:e="dashboard",onNavigate:a,className:r,variant:s="solid"}){let n=(0,f.usePathname)(),i=(0,f.useRouter)(),l=!a,{tooltips:o}=(0,m.useUserSettings)(),c=n&&"/"!==n&&n.startsWith("/chat")?"chat":"dashboard",d=l?c:e;return(0,t.jsxs)("aside",{className:(0,u.cn)("fixed top-[20px] left-[24px] bottom-[20px] flex flex-col z-40 rounded-[var(--radius-md)] w-14","glass"===s?"glass":"bg-surface border border-border",r),children:[(0,t.jsx)("div",{className:"flex items-center justify-center pt-5 pb-[60px]",children:(0,t.jsx)("button",{type:"button","aria-label":"Go to Dashboard",onClick:()=>l?i.push("/"):a?.("dashboard"),className:"flex items-center justify-center transition-opacity hover:opacity-85 cursor-pointer",children:(0,t.jsx)(h,{className:"h-[36px] w-[36px] min-h-[36px] min-w-[36px] shrink-0 text-[var(--logo-color)] -mt-[3px]"})})}),(0,t.jsx)("nav",{className:"flex-1 space-y-1 px-2",children:v.map(e=>{let r=d===e.id,s=(0,t.jsx)("button",{onClick:()=>l?i.push(e.href):a?.(e.id),className:(0,u.cn)("flex items-center justify-center w-full rounded-[4px] p-2.5 cursor-pointer",r?"bg-accent/10 text-accent":"text-foreground-secondary hover:text-foreground hover:bg-surface-hover"),children:(0,t.jsx)(e.icon,{className:"h-5 w-5 shrink-0"})});return o?(0,t.jsx)(x.Tooltip,{content:e.label,side:"right",children:s},e.id):(0,t.jsx)("div",{children:s},e.id)})}),(0,t.jsx)(y,{})]})}function y(){let[e,s]=(0,a.useState)(!1),{theme:n,setTheme:i}=(0,r.useTheme)(),[u,h]=(0,a.useState)(!1),x=(0,f.useRouter)(),{avatarUrl:v,isLoading:b}=(0,m.useUserSettings)(),{getStatus:y}=(0,p.useAgentStatus)(),w=y(p.USER_STATUS_ID),j=(0,a.useRef)(null);(0,a.useEffect)(()=>{h(!0)},[]),(0,a.useEffect)(()=>{function e(e){j.current&&!j.current.contains(e.target)&&s(!1)}return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[]);let k="dark"===n;return(0,t.jsxs)("div",{ref:j,className:"relative flex justify-center pb-[8px]",children:[(0,t.jsx)("button",{onClick:()=>s(!e),className:"group flex items-center justify-center rounded-[4px] cursor-pointer transition-opacity",children:(0,t.jsx)(g.Avatar,{size:"sm",status:"active"===w?"online":"offline",children:b?(0,t.jsx)(g.AvatarFallback,{className:"skeleton"}):v?(0,t.jsx)(g.AvatarImage,{src:v,alt:"You",className:"grayscale group-hover:grayscale-0 transition-all duration-200"}):(0,t.jsx)(g.AvatarFallback,{className:"text-foreground-secondary",children:(0,t.jsx)(l.User,{className:"h-5 w-5"})})})}),e&&(0,t.jsxs)("div",{className:"absolute left-[calc(100%+8px)] bottom-0 w-48 rounded-[var(--radius-md)] bg-surface border border-border shadow-xl py-1 z-50",children:[(0,t.jsxs)("button",{onClick:()=>{s(!1),x.push("/settings")},className:"flex items-center gap-3 w-full px-4 py-2.5 text-sm text-foreground-secondary hover:text-foreground hover:bg-surface-hover cursor-pointer",children:[(0,t.jsx)(d,{className:"h-4 w-4"}),"Settings"]}),u&&(0,t.jsxs)("button",{onClick:()=>{i(k?"light":"dark"),s(!1)},className:"flex items-center gap-3 w-full px-4 py-2.5 text-sm text-foreground-secondary hover:text-foreground hover:bg-surface-hover cursor-pointer",children:[k?(0,t.jsx)(o,{className:"h-4 w-4"}):(0,t.jsx)(c,{className:"h-4 w-4"}),k?"Light mode":"Dark mode"]})]})]})}e.s(["Sidebar",()=>b],94037)},68553,e=>{"use strict";let t=(0,e.i(75254).default)("camera",[["path",{d:"M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z",key:"18u6gg"}],["circle",{cx:"12",cy:"13",r:"3",key:"1vg3eu"}]]);e.s(["Camera",()=>t],68553)},52683,e=>{"use strict";var t=e.i(18050),a=e.i(71645),r=e.i(31245),s=e.i(75254);let n=(0,s.default)("wifi",[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M2 8.82a15 15 0 0 1 20 0",key:"dnpr2z"}],["path",{d:"M5 12.859a10 10 0 0 1 14 0",key:"1x1e6c"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}]]);var i=e.i(57212);let l=(0,s.default)("crown",[["path",{d:"M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z",key:"1vdc57"}],["path",{d:"M5 21h14",key:"11awu3"}]]);var o=e.i(16715),c=e.i(31278),d=e.i(63209),u=e.i(68553),h=e.i(94037),x=e.i(41613),f=e.i(15288),m=e.i(87486),p=e.i(99676),g=e.i(75157),v=e.i(29143),b=e.i(57401),y=e.i(40871);function w({agent:e,isPrimary:r,isConnected:s,onAvatarUpdated:n}){let i=(0,a.useRef)(null),[o,d]=(0,a.useState)(!1),{getStatus:h}=(0,b.useAgentStatus)(),x=h(e.id),v=(0,a.useCallback)(()=>{s&&i.current?.click()},[s]),y=(0,a.useCallback)(async t=>{let a=t.target.files?.[0];if(a){if(t.target.value="",a.size>5242880)return void alert("Image too large (max 5MB)");d(!0);try{let t=new FormData;t.append("avatar",a);let r=await fetch(`/api/openclaw/agents/${e.id}/avatar`,{method:"POST",body:t}),s=await r.json();if(!r.ok)return void alert(s.error||"Failed to update avatar");n()}catch{alert("Failed to upload avatar")}finally{d(!1)}}},[e.id,n]);return(0,t.jsx)(f.Card,{variant:"bordered",className:(0,g.cn)("py-4 pl-5 pr-4 transition-colors min-h-[80px] flex items-center",s?"hover:border-border-hover":"opacity-60"),children:(0,t.jsxs)("div",{className:"flex items-center justify-between flex-1",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsxs)("button",{type:"button",onClick:v,disabled:!s||o,className:"relative group rounded-[4px] focus:outline-none focus-visible:ring-2 focus-visible:ring-accent leading-[0]",title:s?"Click to change avatar":void 0,children:[(0,t.jsx)(p.Avatar,{size:"md",status:function(e,t){if(!t)return"offline";switch(e){case"thinking":return"away";case"active":return"online";default:return"offline"}}(x,s),statusPulse:"thinking"===x,children:e.avatar?(0,t.jsx)(p.AvatarImage,{src:e.avatar,alt:e.name,className:(0,g.cn)(!s&&"grayscale")}):(0,t.jsx)(p.AvatarFallback,{children:e.emoji||e.name.slice(0,2).toUpperCase()})}),s&&!o&&(0,t.jsx)("div",{className:"absolute inset-0 rounded-[4px] bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center",children:(0,t.jsx)(u.Camera,{className:"h-4 w-4 text-white"})}),o&&(0,t.jsx)("div",{className:"absolute inset-0 rounded-[4px] bg-black/50 flex items-center justify-center",children:(0,t.jsx)(c.Loader2,{className:"h-4 w-4 text-white animate-spin"})})]}),(0,t.jsx)("input",{ref:i,type:"file",accept:"image/png,image/jpeg,image/webp,image/gif",className:"hidden",onChange:y}),(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:e.name}),r&&(0,t.jsxs)("span",{className:"flex items-center gap-1 text-xs text-accent",children:[(0,t.jsx)(l,{className:"h-3 w-3"}),"Primary"]})]}),(0,t.jsx)("p",{className:"text-xs text-foreground-muted",children:s?e.description||"OpenClaw Agent":"Unreachable"})]})]}),(0,t.jsx)(m.Badge,{variant:function(e,t){if(!t)return"outline";switch(e){case"thinking":return"warning";case"active":return"success";default:return"outline"}}(x,s),size:"sm",children:function(e,t){if(!t)return"Offline";switch(e){case"thinking":return"Thinking";case"active":return"Active";default:return"Idle"}}(x,s)})]})})}function j({isConnected:e,isLoading:a,isConfigured:r,serverVersion:s,latency:l,error:d,onRefresh:u}){return(0,t.jsx)(f.Card,{variant:"bordered",className:"mb-8",children:(0,t.jsxs)(f.CardContent,{className:"flex items-center justify-between",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[a?(0,t.jsx)(c.Loader2,{className:"h-5 w-5 text-foreground-muted animate-spin"}):e?(0,t.jsx)(n,{className:"h-5 w-5 text-success"}):(0,t.jsx)(i.WifiOff,{className:"h-5 w-5 text-error"}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:"OpenClaw Gateway"}),(0,t.jsx)("p",{className:"text-xs text-foreground-muted",children:(()=>{if(a)return"Connecting to Gateway...";if(!r)return"OpenClaw not installed — visit openclaw.ai";if(e){let e=["Connected"];return s&&(e[0]=`Connected to OpenClaw ${s}`),l&&e.push(`${l}ms`),e.join(" · ")}return d||"Not connected"})()})]})]}),(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("button",{onClick:u,className:"p-1.5 rounded-md text-foreground-muted hover:text-foreground hover:bg-surface-hover transition-colors",title:"Refresh connection",children:(0,t.jsx)(o.RefreshCw,{className:"h-4 w-4"})}),a?(0,t.jsx)(m.Badge,{variant:"outline",children:"Connecting..."}):(0,t.jsx)(m.Badge,{variant:e?"success":r?"error":"outline",children:e?"Connected":r?"Disconnected":"Not Installed"})]})]})})}function k(){return(0,t.jsx)("div",{className:"grid gap-3",children:[1,2,3].map(e=>(0,t.jsx)(f.Card,{variant:"bordered",className:"p-4 min-h-[80px] flex items-center",children:(0,t.jsxs)("div",{className:"flex items-center justify-between flex-1",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsx)("div",{className:"skeleton h-10 w-10 rounded-full"}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("div",{className:"skeleton h-4 w-24 rounded"}),(0,t.jsx)("div",{className:"skeleton h-3 w-32 rounded"})]})]}),(0,t.jsx)("div",{className:"skeleton h-5 w-14 rounded-full"})]})},e))})}function N({isConfigured:e}){return(0,t.jsx)(f.Card,{variant:"bordered",className:"p-8",children:(0,t.jsx)("div",{className:"flex flex-col items-center text-center gap-3",children:e?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(d.AlertCircle,{className:"h-8 w-8 text-foreground-muted"}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:"No agents discovered"}),(0,t.jsx)("p",{className:"text-xs text-foreground-muted mt-1",children:"Make sure OpenClaw Gateway is running and agents are configured."})]})]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.Bot,{className:"h-8 w-8 text-foreground-muted"}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:"Welcome to Castle"}),(0,t.jsxs)("p",{className:"text-xs text-foreground-muted mt-1",children:["Run ",(0,t.jsx)("code",{className:"px-1 py-0.5 bg-surface-hover rounded text-xs",children:"castle setup"})," to connect to your OpenClaw Gateway."]})]})]})})})}function C(){let{status:e,isLoading:a,isConnected:s,isConfigured:n,latency:i,serverVersion:l,agents:o,agentsLoading:c,refresh:d}=(0,v.useOpenClaw)();return(0,t.jsxs)("div",{className:"min-h-screen bg-background",children:[(0,t.jsx)(h.Sidebar,{variant:"solid"}),(0,t.jsxs)("main",{className:"min-h-screen ml-[80px]",children:[(0,t.jsxs)("div",{className:"px-8 py-5 flex items-center justify-between gap-4 border-b border-border",children:[(0,t.jsx)(x.PageHeader,{title:"Castle",subtitle:"The multi-agent workspace"}),(0,t.jsx)(y.SearchTrigger,{})]}),(0,t.jsxs)("div",{className:"p-8 max-w-4xl",children:[(0,t.jsx)(j,{isConnected:s,isLoading:a,isConfigured:n,serverVersion:l,latency:i,error:e?.error,onRefresh:d}),(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between",children:[(0,t.jsxs)("h2",{className:"text-lg font-semibold text-foreground flex items-center gap-2",children:[(0,t.jsx)(r.Bot,{className:"h-5 w-5 text-foreground-secondary"}),"Agents"]}),!a&&o.length>0&&(0,t.jsxs)("span",{className:"text-sm text-foreground-muted",children:[o.length," agent",1!==o.length?"s":""," discovered"]})]}),c||a&&0===o.length?(0,t.jsx)(k,{}):o.length>0?(0,t.jsx)("div",{className:"grid gap-3",children:o.map((e,a)=>(0,t.jsx)(w,{agent:e,isPrimary:0===a,isConnected:s,onAvatarUpdated:d},e.id))}):(0,t.jsx)(N,{isConfigured:n})]})]})]})]})}e.s(["default",()=>C],52683)}]);
|
|
@@ -2,6 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to Castle are documented here.
|
|
4
4
|
|
|
5
|
+
## 0.4.3 (2026-02-12)
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- **Agent avatar storage** — agent avatars are now saved to Castle's own directory (`~/.castle/avatars/`) instead of each agent's workspace. OpenClaw config is updated via the Gateway's `config.patch` RPC — Castle no longer writes to OpenClaw config or workspace files directly.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- **Agent avatar display** — absolute paths under `~/.castle/avatars/` (from avatar upload) are now correctly resolved to the proxy URL so avatars display in the UI after upload.
|
|
14
|
+
|
|
15
|
+
## 0.4.2 (2026-02-10)
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- **Windows ESM path crash** — `bin/castle.js` now converts the tsx import path to a `file://` URL via `pathToFileURL`, fixing `ERR_UNSUPPORTED_ESM_URL_SCHEME` on Windows where `C:\...` paths are not valid ESM specifiers
|
|
20
|
+
- **Windows winget source error** — `install.ps1` now passes `--source winget` to avoid certificate failures from the Microsoft Store source
|
|
21
|
+
- **install.ps1 encoding** — replaced all Unicode characters (em dashes, box-drawing) with ASCII equivalents to prevent PowerShell parse errors on Windows
|
|
22
|
+
- **OpenClaw install command** — fixed broken PowerShell syntax for auto-installing OpenClaw during `castle setup`; now downloads script to temp file before executing with `-NoOnboard`
|
|
23
|
+
- **Silent install failures** — changed OpenClaw install from `stdio: "pipe"` to `stdio: "inherit"` so errors are visible, increased timeout to 5 minutes
|
|
24
|
+
- **Browser open on Windows** — uses native `start` command instead of the `open` npm package which caused a flashing CMD window
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- **Setup no longer exits when OpenClaw is missing** — declining or failing to install OpenClaw now continues setup with defaults instead of exiting; users can reconfigure later with `castle setup`
|
|
29
|
+
- **Smarter connection status** — UI now shows "Not Installed" (outline badge) when OpenClaw isn't configured, instead of the misleading "Disconnected" (red badge)
|
|
30
|
+
|
|
5
31
|
## 0.4.1 (2026-02-10)
|
|
6
32
|
|
|
7
33
|
### Added
|
|
@@ -12,13 +12,13 @@ if (module.enableCompileCache && !process.env.NODE_DISABLE_COMPILE_CACHE) {
|
|
|
12
12
|
// Bootstrap tsx from the package's own node_modules so it works
|
|
13
13
|
// regardless of the user's current working directory.
|
|
14
14
|
import { dirname, resolve } from "path";
|
|
15
|
-
import { fileURLToPath } from "url";
|
|
15
|
+
import { fileURLToPath, pathToFileURL } from "url";
|
|
16
16
|
|
|
17
17
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
18
18
|
|
|
19
19
|
if (!process.env._CASTLE_CLI) {
|
|
20
20
|
const { execFileSync } = await import("child_process");
|
|
21
|
-
const tsxImport = resolve(__dirname, "..", "node_modules", "tsx", "dist", "esm", "index.mjs");
|
|
21
|
+
const tsxImport = pathToFileURL(resolve(__dirname, "..", "node_modules", "tsx", "dist", "esm", "index.mjs")).href;
|
|
22
22
|
try {
|
|
23
23
|
execFileSync(process.execPath, ["--import", tsxImport, ...process.argv.slice(1)], {
|
|
24
24
|
stdio: "inherit",
|
|
@@ -12,7 +12,7 @@ param(
|
|
|
12
12
|
|
|
13
13
|
$ErrorActionPreference = "Stop"
|
|
14
14
|
|
|
15
|
-
#
|
|
15
|
+
# --- Taglines -----------------------------------------------------------------
|
|
16
16
|
|
|
17
17
|
$Taglines = @(
|
|
18
18
|
"Your kingdom awaits, sire."
|
|
@@ -28,7 +28,7 @@ $Taglines = @(
|
|
|
28
28
|
"Every king needs a castle."
|
|
29
29
|
"Where agents serve and dragons compile."
|
|
30
30
|
"The siege of busywork ends here."
|
|
31
|
-
"Hear ye, hear ye
|
|
31
|
+
"Hear ye, hear ye -- your agents await."
|
|
32
32
|
"A castle built on open source bedrock."
|
|
33
33
|
"One does not simply walk in without a CLI."
|
|
34
34
|
"The moat is deep but the docs are deeper."
|
|
@@ -43,7 +43,7 @@ $Taglines = @(
|
|
|
43
43
|
|
|
44
44
|
$Tagline = $Taglines | Get-Random
|
|
45
45
|
|
|
46
|
-
#
|
|
46
|
+
# --- Banner -------------------------------------------------------------------
|
|
47
47
|
|
|
48
48
|
function Print-Banner {
|
|
49
49
|
$banner = @(
|
|
@@ -76,12 +76,12 @@ function Print-Banner {
|
|
|
76
76
|
Write-Host ""
|
|
77
77
|
Write-Host " " -NoNewline
|
|
78
78
|
Write-Host "Castle" -ForegroundColor Blue -NoNewline
|
|
79
|
-
Write-Host "
|
|
79
|
+
Write-Host " - The multi-agent workspace" -ForegroundColor DarkGray
|
|
80
80
|
Write-Host " $Tagline" -ForegroundColor DarkGray
|
|
81
81
|
Write-Host ""
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
#
|
|
84
|
+
# --- Help ---------------------------------------------------------------------
|
|
85
85
|
|
|
86
86
|
function Print-Usage {
|
|
87
87
|
Write-Host "Castle installer (Windows)"
|
|
@@ -107,7 +107,7 @@ function Print-Usage {
|
|
|
107
107
|
Write-Host ' & ([scriptblock]::Create((iwr -useb https://castlekit.com/install.ps1))) -NoOnboard'
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
#
|
|
110
|
+
# --- Environment variable overrides -------------------------------------------
|
|
111
111
|
|
|
112
112
|
if (-not $PSBoundParameters.ContainsKey("Version")) {
|
|
113
113
|
if (-not [string]::IsNullOrWhiteSpace($env:CASTLE_VERSION)) {
|
|
@@ -125,13 +125,13 @@ if (-not $PSBoundParameters.ContainsKey("DryRun")) {
|
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
#
|
|
128
|
+
# --- Helpers ------------------------------------------------------------------
|
|
129
129
|
|
|
130
130
|
function Refresh-Path {
|
|
131
131
|
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
#
|
|
134
|
+
# --- Node.js ------------------------------------------------------------------
|
|
135
135
|
|
|
136
136
|
function Check-Node {
|
|
137
137
|
try {
|
|
@@ -159,7 +159,7 @@ function Install-Node {
|
|
|
159
159
|
# Try winget first (Windows 11 / Windows 10 with App Installer)
|
|
160
160
|
if (Get-Command winget -ErrorAction SilentlyContinue) {
|
|
161
161
|
Write-Host " Using winget..." -ForegroundColor Gray
|
|
162
|
-
winget install OpenJS.NodeJS.LTS --accept-package-agreements --accept-source-agreements
|
|
162
|
+
winget install OpenJS.NodeJS.LTS --source winget --accept-package-agreements --accept-source-agreements
|
|
163
163
|
Refresh-Path
|
|
164
164
|
Write-Host "[OK] Node.js installed via winget" -ForegroundColor Green
|
|
165
165
|
return
|
|
@@ -193,18 +193,18 @@ function Install-Node {
|
|
|
193
193
|
exit 1
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
-
#
|
|
196
|
+
# --- Git ----------------------------------------------------------------------
|
|
197
197
|
|
|
198
198
|
function Check-Git {
|
|
199
199
|
if (Get-Command git -ErrorAction SilentlyContinue) {
|
|
200
200
|
Write-Host "[OK] Git found" -ForegroundColor Green
|
|
201
201
|
return $true
|
|
202
202
|
}
|
|
203
|
-
Write-Host "[!] Git not found (optional
|
|
203
|
+
Write-Host "[!] Git not found (optional -- needed for some npm packages)" -ForegroundColor Yellow
|
|
204
204
|
return $false
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
#
|
|
207
|
+
# --- npm PATH -----------------------------------------------------------------
|
|
208
208
|
|
|
209
209
|
function Ensure-NpmGlobalOnPath {
|
|
210
210
|
$npmPrefix = $null
|
|
@@ -254,7 +254,7 @@ function Resolve-CastleBin {
|
|
|
254
254
|
return $null
|
|
255
255
|
}
|
|
256
256
|
|
|
257
|
-
#
|
|
257
|
+
# --- Existing installation ----------------------------------------------------
|
|
258
258
|
|
|
259
259
|
function Check-ExistingCastle {
|
|
260
260
|
try {
|
|
@@ -266,7 +266,7 @@ function Check-ExistingCastle {
|
|
|
266
266
|
}
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
-
#
|
|
269
|
+
# --- Install Castle -----------------------------------------------------------
|
|
270
270
|
|
|
271
271
|
function Install-Castle {
|
|
272
272
|
$installSpec = "@castlekit/castle@$Version"
|
|
@@ -324,7 +324,7 @@ function Install-Castle {
|
|
|
324
324
|
Write-Host "[OK] Castle installed" -ForegroundColor Green
|
|
325
325
|
}
|
|
326
326
|
|
|
327
|
-
#
|
|
327
|
+
# --- Main ---------------------------------------------------------------------
|
|
328
328
|
|
|
329
329
|
function Main {
|
|
330
330
|
if ($Help) {
|
|
@@ -431,7 +431,7 @@ function Main {
|
|
|
431
431
|
}
|
|
432
432
|
}
|
|
433
433
|
|
|
434
|
-
#
|
|
434
|
+
# --- Entry --------------------------------------------------------------------
|
|
435
435
|
|
|
436
436
|
Print-Banner
|
|
437
437
|
Main
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { NextRequest, NextResponse } from "next/server";
|
|
2
|
-
import {
|
|
2
|
+
import { writeFileSync, mkdirSync } from "fs";
|
|
3
3
|
import { join } from "path";
|
|
4
4
|
import { homedir } from "os";
|
|
5
|
-
import JSON5 from "json5";
|
|
6
5
|
import sharp from "sharp";
|
|
7
6
|
import { ensureGateway } from "@/lib/gateway-connection";
|
|
8
7
|
import { checkCsrf } from "@/lib/api-security";
|
|
@@ -20,21 +19,6 @@ const ALLOWED_TYPES = new Set([
|
|
|
20
19
|
"image/gif",
|
|
21
20
|
]);
|
|
22
21
|
|
|
23
|
-
interface AgentConfig {
|
|
24
|
-
id: string;
|
|
25
|
-
workspace?: string;
|
|
26
|
-
identity?: Record<string, unknown>;
|
|
27
|
-
[key: string]: unknown;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
interface OpenClawConfig {
|
|
31
|
-
agents?: {
|
|
32
|
-
list?: AgentConfig[];
|
|
33
|
-
[key: string]: unknown;
|
|
34
|
-
};
|
|
35
|
-
[key: string]: unknown;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
22
|
/**
|
|
39
23
|
* Resize and compress an avatar image to 256x256, under 100KB.
|
|
40
24
|
*/
|
|
@@ -59,27 +43,13 @@ async function processAvatar(input: Buffer): Promise<{ data: Buffer; ext: string
|
|
|
59
43
|
return { data, ext: ".jpg" };
|
|
60
44
|
}
|
|
61
45
|
|
|
62
|
-
/**
|
|
63
|
-
* Find the OpenClaw config file path.
|
|
64
|
-
*/
|
|
65
|
-
function getOpenClawConfigPath(): string | null {
|
|
66
|
-
const paths = [
|
|
67
|
-
join(homedir(), ".openclaw", "openclaw.json"),
|
|
68
|
-
join(homedir(), ".openclaw", "openclaw.json5"),
|
|
69
|
-
];
|
|
70
|
-
for (const p of paths) {
|
|
71
|
-
if (existsSync(p)) return p;
|
|
72
|
-
}
|
|
73
|
-
return null;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
46
|
/**
|
|
77
47
|
* POST /api/openclaw/agents/[id]/avatar
|
|
78
48
|
*
|
|
79
49
|
* Upload a new avatar image for an agent.
|
|
80
50
|
* - Resizes to 256x256 and compresses under 100KB
|
|
81
|
-
* - Saves to
|
|
82
|
-
* -
|
|
51
|
+
* - Saves to Castle's own avatars directory (~/.castle/avatars/)
|
|
52
|
+
* - Updates OpenClaw config via Gateway's config.patch RPC (never writes to OpenClaw files directly)
|
|
83
53
|
*/
|
|
84
54
|
export async function POST(
|
|
85
55
|
request: NextRequest,
|
|
@@ -128,46 +98,9 @@ export async function POST(
|
|
|
128
98
|
);
|
|
129
99
|
}
|
|
130
100
|
|
|
131
|
-
//
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
return NextResponse.json(
|
|
135
|
-
{ error: "OpenClaw config file not found" },
|
|
136
|
-
{ status: 500 }
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
let config: OpenClawConfig;
|
|
141
|
-
try {
|
|
142
|
-
config = JSON5.parse(readFileSync(configPath, "utf-8"));
|
|
143
|
-
} catch (err) {
|
|
144
|
-
return NextResponse.json(
|
|
145
|
-
{ error: `Failed to read config: ${err instanceof Error ? err.message : "unknown"}` },
|
|
146
|
-
{ status: 500 }
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const agents = config.agents?.list || [];
|
|
151
|
-
const agent = agents.find((a) => a.id === safeId);
|
|
152
|
-
|
|
153
|
-
if (!agent) {
|
|
154
|
-
return NextResponse.json({ error: "Agent not found" }, { status: 404 });
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if (!agent.workspace) {
|
|
158
|
-
return NextResponse.json(
|
|
159
|
-
{ error: "Agent has no workspace configured" },
|
|
160
|
-
{ status: 400 }
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
const workspacePath = agent.workspace.startsWith("~")
|
|
165
|
-
? join(homedir(), agent.workspace.slice(1))
|
|
166
|
-
: agent.workspace;
|
|
167
|
-
|
|
168
|
-
// Save processed avatar to workspace
|
|
169
|
-
const avatarsDir = join(workspacePath, "avatars");
|
|
170
|
-
const fileName = `avatar${processed.ext}`;
|
|
101
|
+
// Save processed avatar to Castle's own directory — never write to OpenClaw's filesystem
|
|
102
|
+
const avatarsDir = join(homedir(), ".castle", "avatars");
|
|
103
|
+
const fileName = `${safeId}${processed.ext}`;
|
|
171
104
|
const filePath = join(avatarsDir, fileName);
|
|
172
105
|
|
|
173
106
|
try {
|
|
@@ -180,37 +113,64 @@ export async function POST(
|
|
|
180
113
|
);
|
|
181
114
|
}
|
|
182
115
|
|
|
183
|
-
// Update config
|
|
184
|
-
//
|
|
116
|
+
// Update OpenClaw config via Gateway's config.patch RPC — the proper way to
|
|
117
|
+
// modify OpenClaw config without writing to its files directly.
|
|
118
|
+
const gw = ensureGateway();
|
|
119
|
+
|
|
120
|
+
if (!gw.isConnected) {
|
|
121
|
+
// Avatar is saved locally; config update will happen when Gateway reconnects
|
|
122
|
+
return NextResponse.json({
|
|
123
|
+
success: true,
|
|
124
|
+
avatar: filePath,
|
|
125
|
+
size: processed.data.length,
|
|
126
|
+
message: "Avatar saved locally. Gateway not connected — config will update when it reconnects.",
|
|
127
|
+
configUpdated: false,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
185
131
|
try {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
132
|
+
// Use config.patch to set the agent's avatar path.
|
|
133
|
+
// Gateway validates and applies the patch, then hot-reloads.
|
|
134
|
+
await gw.request("config.patch", {
|
|
135
|
+
agents: {
|
|
136
|
+
list: [
|
|
137
|
+
{
|
|
138
|
+
id: safeId,
|
|
139
|
+
identity: {
|
|
140
|
+
avatar: filePath,
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
],
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
console.log(`[Avatar API] Config patched for agent ${safeId}`);
|
|
189
147
|
} catch (err) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
148
|
+
console.error(
|
|
149
|
+
`[Avatar API] config.patch failed for agent ${safeId}:`,
|
|
150
|
+
err instanceof Error ? err.message : "unknown"
|
|
193
151
|
);
|
|
152
|
+
// Avatar is still saved locally — not a total failure
|
|
153
|
+
return NextResponse.json({
|
|
154
|
+
success: true,
|
|
155
|
+
avatar: filePath,
|
|
156
|
+
size: processed.data.length,
|
|
157
|
+
message: "Avatar saved but config update failed. Try restarting the Gateway.",
|
|
158
|
+
configUpdated: false,
|
|
159
|
+
});
|
|
194
160
|
}
|
|
195
161
|
|
|
196
|
-
//
|
|
197
|
-
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
198
|
-
|
|
199
|
-
// Refresh Castle's agent list from the Gateway
|
|
162
|
+
// Emit a signal so SSE clients re-fetch agents
|
|
200
163
|
try {
|
|
201
|
-
|
|
202
|
-
if (gw.isConnected) {
|
|
203
|
-
// Emit a signal so SSE clients re-fetch agents
|
|
204
|
-
gw.emit("agentAvatarUpdated", { agentId: safeId });
|
|
205
|
-
}
|
|
164
|
+
gw.emit("agentAvatarUpdated", { agentId: safeId });
|
|
206
165
|
} catch {
|
|
207
166
|
// Non-critical
|
|
208
167
|
}
|
|
209
168
|
|
|
210
169
|
return NextResponse.json({
|
|
211
170
|
success: true,
|
|
212
|
-
avatar:
|
|
171
|
+
avatar: filePath,
|
|
213
172
|
size: processed.data.length,
|
|
214
173
|
message: "Avatar updated",
|
|
174
|
+
configUpdated: true,
|
|
215
175
|
});
|
|
216
176
|
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
|
+
import { join, resolve } from "path";
|
|
3
|
+
import { homedir } from "os";
|
|
2
4
|
import { ensureGateway } from "@/lib/gateway-connection";
|
|
3
5
|
|
|
4
6
|
export const dynamic = "force-dynamic";
|
|
5
7
|
|
|
8
|
+
const CASTLE_AVATARS_DIR = join(homedir(), ".castle", "avatars");
|
|
9
|
+
|
|
6
10
|
interface AgentIdentity {
|
|
7
11
|
name?: string;
|
|
8
12
|
theme?: string;
|
|
@@ -86,6 +90,14 @@ function resolveAvatarUrl(
|
|
|
86
90
|
return `/api/avatars/${key}`;
|
|
87
91
|
}
|
|
88
92
|
|
|
93
|
+
// Absolute path under ~/.castle/avatars/ (from avatar upload via config.patch)
|
|
94
|
+
if (avatar.startsWith("/") || avatar.startsWith("~")) {
|
|
95
|
+
const normalized = resolve(avatar.replace(/^~/, homedir()));
|
|
96
|
+
if (normalized.startsWith(CASTLE_AVATARS_DIR + "/") || normalized === CASTLE_AVATARS_DIR) {
|
|
97
|
+
return `/api/avatars/${agentId}`;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
89
101
|
return null;
|
|
90
102
|
}
|
|
91
103
|
|
|
@@ -206,7 +206,7 @@ function ConnectionCard({
|
|
|
206
206
|
}) {
|
|
207
207
|
const getSubtitle = () => {
|
|
208
208
|
if (isLoading) return "Connecting to Gateway...";
|
|
209
|
-
if (!isConfigured) return "
|
|
209
|
+
if (!isConfigured) return "OpenClaw not installed — visit openclaw.ai";
|
|
210
210
|
if (isConnected) {
|
|
211
211
|
const parts = ["Connected"];
|
|
212
212
|
if (serverVersion) parts[0] = `Connected to OpenClaw ${serverVersion}`;
|
|
@@ -247,8 +247,8 @@ function ConnectionCard({
|
|
|
247
247
|
{isLoading ? (
|
|
248
248
|
<Badge variant="outline">Connecting...</Badge>
|
|
249
249
|
) : (
|
|
250
|
-
<Badge variant={isConnected ? "success" : "error"}>
|
|
251
|
-
{isConnected ? "Connected" : "Disconnected"}
|
|
250
|
+
<Badge variant={isConnected ? "success" : isConfigured ? "error" : "outline"}>
|
|
251
|
+
{isConnected ? "Connected" : isConfigured ? "Disconnected" : "Not Installed"}
|
|
252
252
|
</Badge>
|
|
253
253
|
)}
|
|
254
254
|
</div>
|