@weppy/roblox-mcp 2.17.8 → 2.17.10
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 +27 -0
- package/README.md +14 -5
- package/dashboard/dist/assets/{AiPromptExamples-FjV57hJp.js → AiPromptExamples-BSFrFYar.js} +1 -1
- package/dashboard/dist/assets/AssetsPage-Bt9gZnJ_.js +61 -0
- package/dashboard/dist/assets/ChangelogPage-C4tBBoXT.js +1 -0
- package/dashboard/dist/assets/{ConfirmModal-Ddk0UX_P.js → ConfirmModal-BbqpSaVw.js} +1 -1
- package/dashboard/dist/assets/ConnectionPage-BStKoHK8.css +1 -0
- package/dashboard/dist/assets/ConnectionPage-Sy7xUWtJ.js +6 -0
- package/dashboard/dist/assets/{ControlsPage-Cl_mQpzx.js → ControlsPage-ECpr55X_.js} +1 -1
- package/dashboard/dist/assets/{GameChangeDetail-br9EgICc.js → GameChangeDetail-DJ0xywJq.js} +1 -1
- package/dashboard/dist/assets/InfoLabel-DAd1I756.js +1 -0
- package/dashboard/dist/assets/OverviewPage-C2xJb1Wf.js +1 -0
- package/dashboard/dist/assets/{PageHeader-Dc41DgFB.js → PageHeader-_z4Dtkbg.js} +1 -1
- package/dashboard/dist/assets/PlaceSelectOptions-Dd_m61bQ.js +1 -0
- package/dashboard/dist/assets/{PlaytestAiPromptExamples-CkR6t6Na.js → PlaytestAiPromptExamples-CNe0qWb1.js} +1 -1
- package/dashboard/dist/assets/{PlaytestPage-ShadLIAO.js → PlaytestPage-DZa14JH0.js} +18 -23
- package/dashboard/dist/assets/{SettingsPage-CGGHBxbL.js → SettingsPage-BiDPnuz8.js} +1 -1
- package/dashboard/dist/assets/SyncPage-BIm9tW0s.css +1 -0
- package/dashboard/dist/assets/SyncPage-EcDvwdB8.js +1 -0
- package/dashboard/dist/assets/Tabs-BoD1I6c5.js +1 -0
- package/dashboard/dist/assets/{CurrentPlaceScope-B6NllTmu.css → Tabs-Ci4-OJm-.css} +1 -1
- package/dashboard/dist/assets/{TierPromoPanel-B0BctivD.js → TierPromoPanel-CQQdO5mK.js} +1 -1
- package/dashboard/dist/assets/ToolsPage-D7ovZ3QM.js +1 -0
- package/dashboard/dist/assets/TooltipText-NA7u0bu6.js +1 -0
- package/dashboard/dist/assets/{UiStudioPage-DzG_JVxv.js → UiStudioPage-wYZQClUu.js} +2 -2
- package/dashboard/dist/assets/{WhatsNewPage-BpSGOLxW.js → WhatsNewPage-D3cvOOAD.js} +1 -1
- package/dashboard/dist/assets/{bot-BCKWpJd_.js → bot-D89pfHg8.js} +1 -1
- package/dashboard/dist/assets/{check-DvBWmDvn.js → check-GVlTbKVy.js} +1 -1
- package/dashboard/dist/assets/{copy-vqzBh0XB.js → copy-DVGVC27v.js} +1 -1
- package/dashboard/dist/assets/index-uP4eoQi-.js +746 -0
- package/dashboard/dist/assets/rotate-ccw-Dxk8CuFi.js +6 -0
- package/dashboard/dist/assets/sample-requests-CQy_WSFJ.js +1 -0
- package/dashboard/dist/assets/{trash-2-zj182u9_.js → trash-2-CEfHj47n.js} +1 -1
- package/dashboard/dist/assets/useLiveUptime-BGDr-4gk.js +1 -0
- package/dashboard/dist/assets/{useSettings-Cme-nLG9.js → useSettings-kOu_k9zT.js} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/dist/index.js +170 -170
- package/package.json +1 -1
- package/roblox-plugin/WeppyRobloxMCP.rbxm +0 -0
- package/dashboard/dist/assets/AssetsPage-DvCSWpoy.js +0 -61
- package/dashboard/dist/assets/ChangelogPage-BrNOX2vc.js +0 -1
- package/dashboard/dist/assets/ConnectionPage-B3fGIK2X.css +0 -1
- package/dashboard/dist/assets/ConnectionPage-B62B5vSh.js +0 -6
- package/dashboard/dist/assets/CurrentPlaceScope-Y25KxsHT.js +0 -1
- package/dashboard/dist/assets/InfoLabel-CAGC3efT.js +0 -1
- package/dashboard/dist/assets/OverviewPage-DxRlbjwz.js +0 -1
- package/dashboard/dist/assets/PlaceSelectOptions-Gd2pK9DL.js +0 -1
- package/dashboard/dist/assets/StatusBadge-Cdfb5vyE.js +0 -1
- package/dashboard/dist/assets/SyncPage-BgbrC3SP.css +0 -1
- package/dashboard/dist/assets/SyncPage-CT2ECSYt.js +0 -1
- package/dashboard/dist/assets/Tabs-CPTkUoYi.css +0 -1
- package/dashboard/dist/assets/Tabs-Dl0dNd8V.js +0 -1
- package/dashboard/dist/assets/ToolsPage-CsFjwKOz.js +0 -1
- package/dashboard/dist/assets/TooltipText-C0DmdntK.js +0 -1
- package/dashboard/dist/assets/index-CG4GxcAc.js +0 -714
- package/dashboard/dist/assets/sample-requests-BqgMpTlQ.js +0 -1
- package/dashboard/dist/assets/useLiveUptime-yZ9iKJ1B.js +0 -1
- /package/dashboard/dist/assets/{StatusBadge-C2zYt5iE.css → useLiveUptime-C2zYt5iE.css} +0 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{f as ge,u as re,r as d,j as e,d as ue,b as F,h as pe,D as ye,L as he,M as me,i as V,a as xe,k as _e,s as Se}from"./index-uP4eoQi-.js";import{I as _}from"./InfoLabel-DAd1I756.js";import{P as je}from"./PageHeader-_z4Dtkbg.js";import{S as ce,f as ae,u as ve}from"./useLiveUptime-BGDr-4gk.js";import{T as te}from"./TooltipText-NA7u0bu6.js";import{C as ee}from"./ConfirmModal-BbqpSaVw.js";import{B as be}from"./bot-D89pfHg8.js";import{C as J}from"./copy-DVGVC27v.js";import{R as ne}from"./rotate-ccw-Dxk8CuFi.js";import"./ConfirmModal.module-DJksQHBd.js";/**
|
|
2
|
+
* @license lucide-react v1.8.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const fe=[["rect",{width:"20",height:"8",x:"2",y:"2",rx:"2",ry:"2",key:"ngkwjq"}],["rect",{width:"20",height:"8",x:"2",y:"14",rx:"2",ry:"2",key:"iecqi9"}],["line",{x1:"6",x2:"6.01",y1:"6",y2:"6",key:"16zg32"}],["line",{x1:"6",x2:"6.01",y1:"18",y2:"18",key:"nzw8ys"}]],Ce=ge("server",fe),we="_container_1h084_2",Ne="_entry_1h084_14",Ie="_timestamp_1h084_21",ke="_message_1h084_27",Be="_warn_1h084_34",Pe="_error_1h084_39",Ae="_empty_1h084_44",G={container:we,entry:Ne,timestamp:Ie,message:ke,warn:Be,error:Pe,empty:Ae};function Le(t){const o=new Date(t);return Number.isNaN(o.getTime())?t:`${String(o.getHours()).padStart(2,"0")}:${String(o.getMinutes()).padStart(2,"0")}`}function Ee({entries:t}){const{t:o}=re(),s=d.useRef(null);return d.useEffect(()=>{const r=s.current;r&&(r.scrollTop=r.scrollHeight)},[t.length]),e.jsx("div",{ref:s,className:G.container,children:t.length===0?e.jsx("div",{className:G.empty,children:o("connection.log.empty","No events yet")}):t.map((r,i)=>e.jsxs("div",{className:`${G.entry} ${r.type?G[r.type]:""}`,children:[e.jsx("span",{className:G.timestamp,children:Le(r.timestamp)}),e.jsx("span",{className:G.message,children:r.message})]},i))})}const oe=50,Me=1e3,$e=45e3;function Te(){const t=new Date;return`${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`}function Re(){const{level:t,status:o,error:s,beginExpectedBridgeRestart:r,endExpectedBridgeRestart:i}=ue(),[u,p]=d.useState(null),[c,E]=d.useState(null),[C,M]=d.useState([]),[U,b]=d.useState("idle"),[$,R]=d.useState(null),z=d.useRef(null),f=d.useRef(0),D=d.useCallback((g,y)=>{M(S=>{const j=[...S,{timestamp:Te(),message:g,type:y}];return j.length>oe?j.slice(-oe):j})},[]),m=d.useCallback(async()=>{try{const g=await F.get("/connection-info");p(g)}catch{p(null)}},[]),w=d.useCallback(async()=>{try{const g=await F.get("/api/dashboard/studio-routing");E(g)}catch{E(null)}},[]),H=d.useCallback(async g=>{const y=await F.patch("/api/dashboard/studio-routing",g);return E(y),await m(),y},[m]),B=d.useCallback(async()=>{try{const g=await F.get("/api/dashboard/connection-log");M(g.entries??[])}catch{M([])}},[]),W=d.useCallback(async()=>{await F.post("/api/dashboard/connection-log/clear"),M([])},[]),I=d.useCallback(async g=>{await F.post("/api/dashboard/kill-agent",{instanceId:g}),await m()},[m]),O=d.useCallback((g,y,S)=>{(async()=>{const j=Date.now()+$e;for(;f.current===g&&Date.now()<j;){if(await new Promise(x=>setTimeout(x,Me)),f.current!==g)return;try{const x=await F.get("/status");if(!!!(x.instanceId&&x.sessionId&&x.instanceId!==y&&x.sessionId!==S))continue;if(await Promise.all([m(),w()]),f.current!==g)return;b("succeeded"),R(null),i();return}catch{}}f.current===g&&(b("failed"),R("bridge_restart_timeout"),i())})()},[i,m,w]),P=d.useCallback(async()=>{const g=(o==null?void 0:o.instanceId)??(u==null?void 0:u.serverInstanceId),y=(o==null?void 0:o.sessionId)??(u==null?void 0:u.sessionId);if(!g||!y)return b("failed"),R("bridge_restart_unavailable"),!1;const S=f.current+1;f.current=S,R(null),b("requesting"),r();try{return await F.post("/api/dashboard/bridge/restart",{instanceId:g,sessionId:y}),f.current!==S?!1:(b("reconnecting"),setTimeout(()=>{f.current===S&&O(S,g,y)},0),!0)}catch(j){return f.current!==S||(b("failed"),R(j instanceof pe&&j.error?j.error:"bridge_restart_failed"),i()),!1}},[r,u==null?void 0:u.serverInstanceId,u==null?void 0:u.sessionId,i,O,o==null?void 0:o.instanceId,o==null?void 0:o.sessionId]);return d.useEffect(()=>{t!=="disconnected"&&o?(m(),w()):E(null),B()},[t,o,m,B,w]),d.useEffect(()=>{const g=new ye;z.current=g,g.connect();const y=g.on("connection",j=>{const x=j;x.status!=="updated"&&x.clientId&&D(`Plugin ${x.status} — ${x.clientId}`,x.status==="disconnected"?"warn":"info"),m(),w()}),S=g.on("mcp_status",j=>{const x=j,A=x.status==="registered"?"registered":"unregistered";D(`MCP ${A} — ${x.aiClientName}`,x.status==="registered"?"info":"warn"),m(),w()});return()=>{y(),S(),g.disconnect(),z.current=null}},[D,m,w]),d.useEffect(()=>()=>{f.current+=1,i()},[i]),{status:o,connectionInfo:u,studioRouting:c,connectionLog:C,level:t,error:s,clearConnectionLog:W,killAgent:I,bridgeRestartState:U,bridgeRestartError:$,restartBridge:P,updateStudioRouting:H}}const De="_page_6dxry_2",He="_card_6dxry_11",Ue="_topologyCard_6dxry_19",Oe="_topologyDisconnected_6dxry_26",Fe="_topologyHeader_6dxry_30",We="_topologyIntro_6dxry_38",qe="_topologyNetwork_6dxry_45",Ye="_topologyLinks_6dxry_49",ze="_topologyLink_6dxry_49",Ge="_topologyLink_agent_6dxry_66",Ve="_topologyLink_studio_6dxry_70",Ke="_topologyGrid_6dxry_74",Xe="_topologyColumn_6dxry_83",Je="_topologyColumnHeader_6dxry_90",Qe="_topologyColumnHeaderSpacer_6dxry_101",Ze="_topologyCount_6dxry_105",et="_topologyList_6dxry_120",tt="_topologyListCentered_6dxry_128",nt="_topologyNode_6dxry_132",ot="_topologyNodeTitle_6dxry_140",st="_topologyNodeMeta_6dxry_156",it="_topologyNodeSubtle_6dxry_157",rt="_topologyState_6dxry_170",ct="_topologyEmpty_6dxry_183",at="_topologyOverflow_6dxry_198",lt="_topologyOverflowButton_6dxry_213",dt="_topologyServerColumn_6dxry_236",gt="_topologyServer_6dxry_236",ut="_topologyServerIcon_6dxry_254",pt="_topologyServerBody_6dxry_267",yt="_topologyServerTitle_6dxry_276",ht="_topologyServerMeta_6dxry_283",mt="_routingSummaryCompact_6dxry_290",xt="_disabled_6dxry_298",_t="_cardHeader_6dxry_304",St="_restartButton_6dxry_317",jt="_bridgeActionHint_6dxry_356",vt="_restartProgress_6dxry_363",bt="_restartFailure_6dxry_364",ft="_restartIconSpinning_6dxry_401",Ct="_cardHint_6dxry_417",wt="_clearButton_6dxry_424",Nt="_serverGrid_6dxry_448",It="_statusRow_6dxry_466",kt="_metaItem_6dxry_473",Bt="_table_6dxry_480",Pt="_tableWrap_6dxry_500",At="_routingSummary_6dxry_290",Lt="_manageLink_6dxry_516",Et="_segment_6dxry_542",Mt="_segmentActive_6dxry_543",$t="_targetPrimary_6dxry_577",Tt="_monoMuted_6dxry_581",Rt="_copyIconButton_6dxry_585",Dt="_routingBadge_6dxry_610",Ht="_studioStateBadge_6dxry_624",Ut="_studioState_running_6dxry_639",Ot="_studioState_paused_6dxry_645",Ft="_studioState_edit_6dxry_651",Wt="_studioState_unknown_6dxry_657",qt="_toggleBtn_6dxry_664",Yt="_disconnected_6dxry_679",zt="_disconnectedActions_6dxry_696",Gt="_btn_6dxry_703",Vt="_activity_active_6dxry_721",Kt="_activity_stale_6dxry_722",Xt="_activity_unknown_6dxry_723",Jt="_killBtn_6dxry_747",Qt="_emptyRow_6dxry_771",n={page:De,card:He,topologyCard:Ue,topologyDisconnected:Oe,topologyHeader:Fe,topologyIntro:We,topologyNetwork:qe,topologyLinks:Ye,topologyLink:ze,topologyLink_agent:Ge,topologyLink_studio:Ve,topologyGrid:Ke,topologyColumn:Xe,topologyColumnHeader:Je,topologyColumnHeaderSpacer:Qe,topologyCount:Ze,topologyList:et,topologyListCentered:tt,topologyNode:nt,topologyNodeTitle:ot,topologyNodeMeta:st,topologyNodeSubtle:it,topologyState:rt,topologyEmpty:ct,topologyOverflow:at,topologyOverflowButton:lt,topologyServerColumn:dt,topologyServer:gt,topologyServerIcon:ut,topologyServerBody:pt,topologyServerTitle:yt,topologyServerMeta:ht,routingSummaryCompact:mt,disabled:xt,cardHeader:_t,restartButton:St,bridgeActionHint:jt,restartProgress:vt,restartFailure:bt,restartIconSpinning:ft,"restart-spin":"_restart-spin_6dxry_1",cardHint:Ct,clearButton:wt,serverGrid:Nt,statusRow:It,metaItem:kt,table:Bt,tableWrap:Pt,routingSummary:At,manageLink:Lt,segment:Et,segmentActive:Mt,targetPrimary:$t,monoMuted:Tt,copyIconButton:Rt,routingBadge:Dt,studioStateBadge:Ht,studioState_running:Ut,studioState_paused:Ot,studioState_edit:Ft,studioState_unknown:Wt,toggleBtn:qt,disconnected:Yt,disconnectedActions:zt,btn:Gt,activity_active:Vt,activity_stale:Kt,activity_unknown:Xt,killBtn:Jt,emptyRow:Qt},X=5;function Zt(t){return t?Date.now()-t<3e4?"active":"stale":"unknown"}function en(t,o){return t==="active"?o("connection.topology.active","Active"):t==="stale"?o("connection.topology.stale","Stale"):o("connection.topology.unknown","Unknown")}function se(t){return t.length>10?t.slice(0,10):t}function ie(t,o){return t.replace("{count}",String(o))}function tn(t,o,s){const r=t.studioState??"unknown",i={edit:o("connection.targets.studioState.edit","Edit"),running:o("connection.targets.studioState.running","Running"),paused:o("connection.targets.studioState.paused","Paused"),unknown:o("connection.targets.studioState.unknown","Unknown")},u=t.studioStateSource==="thread"?o("connection.targets.studioState.source.thread","WEPPY play command"):t.studioStateSource==="pluginConnection"?o("connection.targets.studioState.source.pluginConnection","Studio Play/Test connection"):t.studioStateSource==="runService"?o("connection.targets.studioState.source.runService","Studio RunService"):o("connection.targets.studioState.source.unknown","Unknown source"),p=t.studioStateUpdatedAt?s(t.studioStateUpdatedAt):o("connection.targets.studioState.updatedUnknown","not reported");return{state:r,label:i[r],tooltip:`${u} · ${p}`}}function nn(t,o){return t.length!==o.length?!1:t.every((s,r)=>{const i=o[r];return i!==void 0&&s.id===i.id&&s.side===i.side&&Math.abs(s.x1-i.x1)<.5&&Math.abs(s.y1-i.y1)<.5&&Math.abs(s.x2-i.x2)<.5&&Math.abs(s.y2-i.y2)<.5})}function k(t,o,s){return{x:o-t.left,y:s-t.top}}function on(t,o,s,r){if(o.right<=s.left){const p=k(r,o.right,o.top+o.height/2),c=k(r,s.left,s.top+s.height/2);return{id:t,side:"agent",x1:p.x,y1:p.y,x2:c.x,y2:c.y}}if(o.bottom<=s.top){const p=k(r,o.left+o.width/2,o.bottom),c=k(r,s.left+s.width/2,s.top);return{id:t,side:"agent",x1:p.x,y1:p.y,x2:c.x,y2:c.y}}const i=k(r,o.left+o.width/2,o.top),u=k(r,s.left+s.width/2,s.bottom);return{id:t,side:"agent",x1:i.x,y1:i.y,x2:u.x,y2:u.y}}function sn(t,o,s,r){if(s.right<=o.left){const p=k(r,o.left,o.top+o.height/2),c=k(r,s.right,s.top+s.height/2);return{id:t,side:"studio",x1:p.x,y1:p.y,x2:c.x,y2:c.y}}if(s.bottom<=o.top){const p=k(r,o.left+o.width/2,o.top),c=k(r,s.left+s.width/2,s.bottom);return{id:t,side:"studio",x1:p.x,y1:p.y,x2:c.x,y2:c.y}}const i=k(r,o.left+o.width/2,o.bottom),u=k(r,s.left+s.width/2,s.top);return{id:t,side:"studio",x1:i.x,y1:i.y,x2:u.x,y2:u.y}}function rn({agents:t,isDisconnected:o,pinnedTargetClientId:s,priorityTarget:r,status:i,studioRoutingMode:u,studioTargets:p,t:c,timeAgo:E,onCopySelector:C,onManageRouting:M}){const[U,b]=d.useState(!1),[$,R]=d.useState(!1),[z,f]=d.useState([]),D=d.useRef(null),m=d.useRef(null),w=d.useRef(new Map),H=d.useRef(new Map),B=u==="pinned"?c("connection.routing.pinned","Manual: Pinned Studio"):c("connection.routing.recentPriority","Automatic: Recent priority"),W=o?"offline":"online",I=d.useMemo(()=>U?t:t.slice(0,X),[t,U]),O=Math.max(0,t.length-I.length),P=d.useMemo(()=>$?p:p.slice(0,X),[p,$]),g=Math.max(0,p.length-P.length),y=[n.topologyList,I.length<=1?n.topologyListCentered:""].filter(Boolean).join(" "),S=[n.topologyList,P.length<=1?n.topologyListCentered:""].filter(Boolean).join(" "),j=d.useCallback(a=>h=>{if(h){w.current.set(a,h);return}w.current.delete(a)},[]),x=d.useCallback(a=>h=>{if(h){H.current.set(a,h);return}H.current.delete(a)},[]),A=d.useCallback(()=>{const a=D.current,h=m.current;if(!a||!h){f([]);return}const v=a.getBoundingClientRect(),N=h.getBoundingClientRect(),L=[];I.forEach(T=>{const q=w.current.get(T.instanceId);q&&L.push(on(`agent-${T.instanceId}`,q.getBoundingClientRect(),N,v))}),P.forEach(T=>{const q=H.current.get(T.clientId);q&&L.push(sn(`studio-${T.clientId}`,q.getBoundingClientRect(),N,v))}),f(T=>nn(T,L)?T:L)},[I,P]);return d.useLayoutEffect(()=>{A();const a=[D.current,m.current,...I.map(v=>w.current.get(v.instanceId)),...P.map(v=>H.current.get(v.clientId))].filter(v=>v!=null);if(window.addEventListener("resize",A),typeof ResizeObserver>"u")return()=>{window.removeEventListener("resize",A)};const h=new ResizeObserver(A);return a.forEach(v=>h.observe(v)),()=>{window.removeEventListener("resize",A),h.disconnect()}},[A,I,P]),e.jsxs("section",{className:`${n.topologyCard} ${o?n.topologyDisconnected:""}`,"aria-label":c("connection.topology.ariaLabel","Connection topology"),children:[e.jsxs("div",{className:n.topologyHeader,children:[e.jsxs("div",{children:[e.jsx("div",{className:n.cardHeader,children:c("connection.topology.title","Connection topology")}),e.jsx("p",{className:n.topologyIntro,children:c("connection.topology.description","Each AI agent connects through its own MCP Adapter to one shared WEPPY Bridge, which keeps Roblox Studio connected.")})]}),e.jsx(he,{to:"/controls?section=studio-routing",className:n.manageLink,onClick:M,children:c("connection.routing.manage","Manage routing")})]}),e.jsxs("div",{className:n.topologyNetwork,ref:D,children:[e.jsx("svg",{"aria-hidden":"true",className:n.topologyLinks,"data-testid":"topology-connection-lines",focusable:"false",children:z.map(a=>e.jsx("line",{className:`${n.topologyLink} ${n[`topologyLink_${a.side}`]}`,"data-side":a.side,vectorEffect:"non-scaling-stroke",x1:a.x1,x2:a.x2,y1:a.y1,y2:a.y2},a.id))}),e.jsxs("div",{className:n.topologyGrid,children:[e.jsxs("div",{className:n.topologyColumn,children:[e.jsxs("div",{className:n.topologyColumnHeader,children:[e.jsx(be,{size:15,"aria-hidden":"true"}),e.jsx("span",{children:c("connection.agents.title","AI Agents")}),e.jsx("span",{className:n.topologyCount,children:t.length})]}),e.jsxs("div",{className:y,children:[t.length>0?I.map(a=>{const h=Zt(a.lastSeen),v=a.aiClientName??se(a.instanceId),N=a.lastSeen,L=a.mcpVersion?`${c("connection.topology.adapterRole","MCP Adapter")} v${a.mcpVersion}`:c("connection.topology.adapterRole","MCP Adapter");return e.jsxs("div",{className:n.topologyNode,ref:j(a.instanceId),children:[e.jsxs("div",{className:n.topologyNodeTitle,children:[e.jsx("span",{className:n[`activity_${h}`]}),e.jsx("strong",{children:v}),e.jsx("span",{className:n.topologyState,children:en(h,c)})]}),e.jsxs("div",{className:n.topologyNodeMeta,children:[e.jsx("span",{children:L})," ·"," ",c("connection.server.session","Session")," ",se(a.instanceId)," ·"," ",N?`${c("connection.topology.lastContact","Last contact")} ${E(N)}`:c("connection.topology.noContact","No recent contact")]})]},a.instanceId)}):e.jsx("div",{className:n.topologyEmpty,children:c("connection.agents.none","No agents connected")}),t.length>X?e.jsxs("div",{className:n.topologyOverflow,children:[O>0?e.jsx("span",{children:ie(c("connection.topology.moreAgents","+{count} more agents"),O)}):e.jsx("span",{children:c("connection.topology.allAgentsVisible","All agents visible")}),e.jsx("button",{type:"button",className:n.topologyOverflowButton,"aria-label":U?c("connection.topology.showLessAgents","Show less AI agents"):c("connection.topology.showAllAgents","Show all AI agents"),onClick:()=>b(a=>!a),children:U?c("connection.topology.showLess","Show less"):c("connection.topology.showAll","Show all")})]}):null]})]}),e.jsxs("div",{className:n.topologyServerColumn,children:[e.jsx("div",{className:n.topologyColumnHeaderSpacer,"aria-hidden":"true"}),e.jsxs("div",{className:`${n.topologyNode} ${n.topologyServer}`,ref:m,children:[e.jsx("div",{className:n.topologyServerIcon,children:e.jsx(Ce,{size:18,"aria-hidden":"true"})}),e.jsxs("div",{className:n.topologyServerBody,children:[e.jsx("div",{className:n.topologyServerTitle,children:c("connection.topology.serverTitle","WEPPY Bridge")}),e.jsx(ce,{status:W}),e.jsxs("div",{className:n.topologyServerMeta,children:[i!=null&&i.version?`v${i.version}`:c("connection.topology.versionUnknown","Version unknown"),i!=null&&i.sessionId?` · ${c("connection.server.session","Session")} ${i.sessionId.slice(0,8)}`:""]}),(i==null?void 0:i.pid)!=null||(i==null?void 0:i.uptime)!=null?e.jsxs("div",{className:n.topologyNodeSubtle,children:[(i==null?void 0:i.pid)!=null?e.jsx("span",{children:`${c("connection.server.pid","PID")} ${i.pid}`}):null,(i==null?void 0:i.pid)!=null&&(i==null?void 0:i.uptime)!=null?" · ":"",(i==null?void 0:i.uptime)!=null?e.jsx("span",{children:`${c("connection.server.uptime","Uptime")} ${ae(i.uptime)}`}):null]}):null,e.jsx("div",{className:n.routingSummaryCompact,children:e.jsx("span",{className:n.routingBadge,children:B})})]})]})]}),e.jsxs("div",{className:n.topologyColumn,children:[e.jsxs("div",{className:n.topologyColumnHeader,children:[e.jsx(me,{size:15,"aria-hidden":"true"}),e.jsx("span",{children:c("connection.targets.title","Studio Targets")}),e.jsx("span",{className:n.topologyCount,children:p.length})]}),e.jsxs("div",{className:S,children:[p.length>0?P.map(a=>{const h=u==="pinned"&&s===a.clientId,v=u==="recentPriority"&&(r==null?void 0:r.clientId)===a.clientId,N=tn(a,c,E);return e.jsxs("div",{className:n.topologyNode,ref:x(a.clientId),children:[e.jsxs("div",{className:n.topologyNodeTitle,children:[e.jsx("span",{className:n.targetPrimary,children:a.targetAlias}),e.jsx(V,{text:c("connection.targets.copyTargetAlias","Copy Studio ID"),children:e.jsx("button",{type:"button",className:n.copyIconButton,"aria-label":c("connection.targets.copyTargetAlias","Copy Studio ID"),onClick:()=>C(a.targetAlias,"target_alias"),children:e.jsx(J,{size:13,"aria-hidden":"true"})})}),h?e.jsx("span",{className:n.routingBadge,children:c("connection.routing.pinnedBadge","Pinned")}):v?e.jsx("span",{className:n.routingBadge,children:c("connection.routing.priorityBadge","Priority")}):null,e.jsx(V,{text:N.tooltip,children:e.jsx("span",{className:`${n.studioStateBadge} ${n[`studioState_${N.state}`]}`,children:N.label})})]}),e.jsxs("div",{className:n.topologyNodeMeta,children:[e.jsx("span",{children:a.placeName??c("connection.topology.placeUnknown","Place unknown")}),a.placeId!==void 0?` · ${a.placeId}`:""]}),e.jsxs("div",{className:n.topologyNodeSubtle,children:[a.connectionState," · ",c("connection.targets.lastSeen","Last Seen")," ",E(a.lastSeen)]})]},a.clientId)}):e.jsx("div",{className:n.topologyEmpty,children:c("connection.targets.none","No Studio targets connected. Open Roblox Studio and connect WEPPY Plugin.")}),p.length>X?e.jsxs("div",{className:n.topologyOverflow,children:[g>0?e.jsx("span",{children:ie(c("connection.topology.moreStudios","+{count} more studios"),g)}):e.jsx("span",{children:c("connection.topology.allStudiosVisible","All studios visible")}),e.jsx("button",{type:"button",className:n.topologyOverflowButton,"aria-label":$?c("connection.topology.showLessStudios","Show less Studio targets"):c("connection.topology.showAllStudios","Show all Studio targets"),onClick:()=>R(a=>!a),children:$?c("connection.topology.showLess","Show less"):c("connection.topology.showAll","Show all")})]}):null]})]})]})]})]})}function Y(t,o){const s=Math.max(0,Math.floor((Date.now()-t)/1e3));return s<60?`${s}${o("connection.time.secondsAgo","s ago")}`:s<3600?`${Math.floor(s/60)}${o("connection.time.minutesAgo","m ago")}`:`${Math.floor(s/3600)}${o("connection.time.hoursAgo","h ago")}`}function cn(t){return t?Date.now()-t<3e4?"active":"stale":"unknown"}function an(t,o){const s=t.studioState??"unknown",r={edit:o("connection.targets.studioState.edit","Edit"),running:o("connection.targets.studioState.running","Running"),paused:o("connection.targets.studioState.paused","Paused"),unknown:o("connection.targets.studioState.unknown","Unknown")},i=t.studioStateSource==="thread"?o("connection.targets.studioState.source.thread","WEPPY play command"):t.studioStateSource==="pluginConnection"?o("connection.targets.studioState.source.pluginConnection","Studio Play/Test connection"):t.studioStateSource==="runService"?o("connection.targets.studioState.source.runService","Studio RunService"):o("connection.targets.studioState.source.unknown","Unknown source"),u=t.studioStateUpdatedAt?Y(t.studioStateUpdatedAt,o):o("connection.targets.studioState.updatedUnknown","not reported"),p=t.playtestMode&&t.playtestMode!=="unknown"?` · ${t.playtestMode}`:"";return{state:s,label:`${r[s]}${p}`,tooltip:`${i} · ${u}`}}function Sn(){const{t}=re(),{trackEvent:o}=xe(),{status:s,connectionInfo:r,studioRouting:i,connectionLog:u,level:p,clearConnectionLog:c,killAgent:E,bridgeRestartState:C,bridgeRestartError:M,restartBridge:U}=Re(),{show:b}=_e(),[$,R]=d.useState(!0),[z,f]=d.useState(!1),[D,m]=d.useState(!1),[w,H]=d.useState(!1),[B,W]=d.useState(null),[I,O]=d.useState(!1),P=ve(s==null?void 0:s.uptime),g=d.useRef(C),y=p==="disconnected",S=C==="requesting"||C==="reconnecting",j=((r==null?void 0:r.mcpInstanceCount)??0)>0,x=!!(((s==null?void 0:s.instanceId)??(r==null?void 0:r.serverInstanceId))&&((s==null?void 0:s.sessionId)??(r==null?void 0:r.sessionId))),A=!y&&!S&&j&&x,a=y?"offline":"online",h=(i==null?void 0:i.studioRoutingMode)??(s==null?void 0:s.studioRoutingMode)??"recentPriority",v=(i==null?void 0:i.pinnedTargetClientId)??(s==null?void 0:s.pinnedTargetClientId)??null,N=Se((i==null?void 0:i.targets)??(s==null?void 0:s.pluginClients)??[],h,v),L=(i==null?void 0:i.priorityTarget)??N[0];d.useEffect(()=>{const l=g.current;g.current=C,l!==C&&(C==="succeeded"?b(t("connection.server.restartSucceeded","WEPPY Bridge restarted"),"success"):C==="failed"&&b(t("connection.server.restartFailed","WEPPY Bridge could not be restarted"),"error"))},[C,b,t]);const T=M==="bridge_restart_timeout"?t("connection.server.restartTimeout","The new Bridge did not become ready in time. Check the MCP connection in your AI tool, then try again."):M==="bridge_restart_stale"?t("connection.server.restartStale","The Bridge changed before the restart request was accepted. Refresh the current status and try again."):M==="bridge_restart_unavailable"?t("connection.server.restartUnavailable","Connect at least one AI Agent before restarting so its MCP Adapter can start the new Bridge."):t("connection.server.restartFailed","WEPPY Bridge could not be restarted"),q=async()=>{await U()&&m(!1)},le=async()=>{if(B){O(!0);try{await E(B.instanceId),b(t("connection.agents.killed","Agent killed"),"success"),W(null)}catch{b(t("connection.agents.killFailed","Failed to kill agent"),"error")}finally{O(!1)}}},de=async()=>{H(!0);try{await c(),b(t("toast.clearSuccess","Cleared successfully"),"success"),f(!1)}catch{b(t("toast.clearFailed","Failed to clear data"),"error")}finally{H(!1)}},K=async(l,Q)=>{try{await navigator.clipboard.writeText(l),b(t("connection.targets.copied","Copied value"),"success"),o("dashboard_click_event",{click_target:`connection_copy_${Q}`,page:"connection"})}catch{b(t("connection.targets.copyFailed","Failed to copy value"),"error")}};return e.jsxs("div",{className:n.page,children:[e.jsx(je,{title:t("page.connection.title","Connection"),description:t("page.connection.description","Inspect WEPPY Bridge, MCP Adapter, Studio Plugin, and connection log status."),helpTopicId:"connection",helpState:{connectionLevel:p}}),e.jsx(rn,{agents:(r==null?void 0:r.mcpInstances)??[],isDisconnected:y&&!S,pinnedTargetClientId:v,priorityTarget:L,status:s??null,studioRoutingMode:h,studioTargets:N,t,timeAgo:l=>Y(l,t),onCopySelector:K,onManageRouting:()=>o("dashboard_click_event",{click_target:"connection_manage_routing",page:"connection"})}),e.jsxs("div",{className:n.card,children:[e.jsxs("div",{className:n.cardHeader,children:[e.jsx("span",{children:t("connection.server.title","Bridge Status")}),e.jsxs("button",{type:"button",className:n.restartButton,disabled:!A,title:j?void 0:t("connection.server.restartUnavailable","Connect at least one AI Agent before restarting so its MCP Adapter can start the new Bridge."),onClick:()=>{o("dashboard_click_event",{click_target:"connection_restart_bridge",page:"connection"}),m(!0)},children:[e.jsx(ne,{size:14,"aria-hidden":"true",className:S?n.restartIconSpinning:void 0}),S?t("connection.server.restarting","Restarting…"):t("connection.server.restart","Restart Bridge")]})]}),!j&&!y?e.jsx("p",{className:n.bridgeActionHint,children:t("connection.server.restartUnavailable","Connect at least one AI Agent before restarting so its MCP Adapter can start the new Bridge.")}):null,S?e.jsxs("div",{className:n.restartProgress,role:"status","aria-live":"polite",children:[e.jsx(ne,{size:18,"aria-hidden":"true",className:n.restartIconSpinning}),e.jsxs("div",{children:[e.jsx("strong",{children:C==="requesting"?t("connection.server.restartRequesting","Requesting Bridge restart…"):t("connection.server.restartReconnecting","Reconnecting to WEPPY Bridge…")}),e.jsx("p",{children:t("connection.server.restartWaiting","Dashboard and Studio connections will return automatically when the new Bridge is ready.")})]})]}):C==="failed"?e.jsxs("div",{className:n.restartFailure,role:"alert",children:[e.jsx("p",{children:T}),e.jsx("button",{type:"button",className:n.btn,onClick:()=>{y?window.location.reload():m(!0)},children:t("common.retry","Retry")})]}):y?e.jsxs("div",{className:n.disconnected,children:[e.jsx("h3",{children:t("level.l0.title")}),e.jsx("p",{children:t("level.l0.message")}),e.jsx("p",{children:t("common.reconnecting")}),e.jsxs("div",{className:n.disconnectedActions,children:[e.jsx("button",{className:n.btn,onClick:()=>window.location.reload(),children:t("connection.reconnect","Reconnect")}),e.jsx("button",{className:n.btn,onClick:()=>{window.location.hash="#/settings"},children:t("connection.checkSettings","Check Settings")})]})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:n.statusRow,children:e.jsx(ce,{status:a})}),e.jsxs("dl",{className:n.serverGrid,children:[(s==null?void 0:s.version)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(_,{label:t("connection.server.version","Version"),tooltip:t("connection.server.version.tooltip","WEPPY Bridge runtime version")})}),e.jsx("dd",{children:e.jsx(te,{text:t("connection.server.version.tooltip","WEPPY Bridge runtime version"),children:`v${s.version}`})})]}),(s==null?void 0:s.pid)!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(_,{label:t("connection.server.pid","PID"),tooltip:t("connection.server.pid.tooltip","Operating system process identifier")})}),e.jsx("dd",{children:s.pid})]}),(s==null?void 0:s.uptime)!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(_,{label:t("connection.server.uptime","Uptime"),tooltip:t("connection.server.uptime.tooltip","Time elapsed since the WEPPY Bridge started")})}),e.jsx("dd",{children:ae(P??s.uptime)})]}),(s==null?void 0:s.sessionId)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(_,{label:t("connection.server.session","Session"),tooltip:t("connection.server.session.tooltip","Current WEPPY Bridge session identifier")})}),e.jsx("dd",{children:s.sessionId.slice(0,8)})]}),(r==null?void 0:r.serverExecutable)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(_,{label:t("connection.server.exec","Exec"),tooltip:t("connection.server.exec.tooltip","Executable path used to launch the WEPPY Bridge")})}),e.jsx("dd",{children:r.serverExecutable})]})]})]})]}),e.jsxs("div",{className:`${n.card} ${y?n.disabled:""}`,children:[e.jsxs("div",{className:n.cardHeader,children:[e.jsxs("span",{children:[t("connection.agents.title","AI Agents")," ","(",(r==null?void 0:r.mcpInstanceCount)??0,")"]}),e.jsx("button",{className:n.toggleBtn,onClick:()=>R(l=>!l),"aria-label":$?t("common.collapse","Collapse"):t("common.expand","Expand"),children:$?"▾":"▸"})]}),$&&e.jsxs("table",{className:n.table,children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:t("connection.agents.name","Agent")}),e.jsx("th",{children:e.jsx(_,{label:t("connection.agents.version","Version"),tooltip:t("connection.agents.version.tooltip","MCP Adapter package version for this agent session")})}),e.jsx("th",{children:e.jsx(_,{label:t("connection.server.pid","PID"),tooltip:t("connection.server.pid.tooltip","Operating system process identifier")})}),e.jsx("th",{children:e.jsx(_,{label:t("connection.agents.projectRoot","Project Root"),tooltip:t("connection.agents.projectRoot.tooltip","Authoritative project root for sync ownership")})}),e.jsx("th",{children:t("connection.agents.connected","Connected")}),e.jsx("th",{children:e.jsx(_,{label:t("connection.agents.lastSeen","Last contact"),tooltip:t("connection.agents.lastSeen.tooltip","Last heartbeat or tool request received from this agent. Check Last Command for tool use.")})}),e.jsx("th",{children:e.jsx(_,{label:t("connection.agents.lastCommand","Last Command"),tooltip:t("connection.agents.lastCommand.tooltip","Most recent tool request from this agent.")})}),e.jsx("th",{})]})}),e.jsx("tbody",{children:r!=null&&r.mcpInstances&&r.mcpInstances.length>0?r.mcpInstances.map(l=>e.jsxs("tr",{children:[e.jsxs("td",{children:[e.jsx("span",{className:n[`activity_${cn(l.lastSeen)}`]}),l.aiClientName??t("connection.agents.unknown","Unknown")]}),e.jsx("td",{children:l.mcpVersion??"-"}),e.jsx("td",{children:l.pid}),e.jsx("td",{children:l.projectRoot??l.cwd??t("connection.agents.projectRoot.unresolved","Unresolved")}),e.jsx("td",{children:Y(l.connectedAt,t)}),e.jsx("td",{children:l.lastSeen?Y(l.lastSeen,t):"-"}),e.jsx("td",{children:l.lastCommandAt?Y(l.lastCommandAt,t):"-"}),e.jsx("td",{children:!l.isServer&&e.jsx("button",{className:n.killBtn,onClick:()=>{o("dashboard_click_event",{click_target:"connection_kill_agent",page:"connection"}),W({instanceId:l.instanceId,name:l.aiClientName??l.instanceId.slice(0,8)})},children:t("connection.agents.kill","Kill")})})]},l.instanceId)):e.jsx("tr",{children:e.jsx("td",{colSpan:8,className:n.emptyRow,children:t("connection.agents.none","No agents connected")})})})]})]}),e.jsxs("div",{className:`${n.card} ${y?n.disabled:""}`,children:[e.jsxs("div",{className:n.cardHeader,children:[t("connection.targets.title","Studio Targets")," ","(",N.length,")"]}),e.jsx("p",{className:n.cardHint,children:t("connection.targets.help","When multiple Studio windows are connected, tell the agent to use Studio ID studio-1 to choose one.")}),e.jsx("div",{className:n.tableWrap,children:e.jsxs("table",{className:n.table,children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:e.jsx(_,{label:t("connection.targets.target","Studio ID"),tooltip:t("connection.targets.target.tooltip","Short name for this Roblox Studio window")})}),e.jsx("th",{children:t("connection.targets.place","Place")}),e.jsx("th",{children:e.jsx(_,{label:t("connection.targets.placeId","Place ID"),tooltip:t("connection.targets.placeId.tooltip","Roblox Place ID for this Studio window")})}),e.jsx("th",{children:e.jsx(_,{label:t("connection.targets.clientId","Connection ID"),tooltip:t("connection.targets.clientId.tooltip","Full connection ID for diagnostics. Usually use Studio ID instead.")})}),e.jsx("th",{children:e.jsx(_,{label:t("connection.targets.studioState","Studio State"),tooltip:t("connection.targets.studioState.tooltip","Current edit/play runtime state reported by this Studio window")})}),e.jsx("th",{children:e.jsx(_,{label:t("connection.targets.session","Session"),tooltip:t("connection.targets.session.tooltip","Command channel state for this Studio target")})}),e.jsx("th",{children:e.jsx(_,{label:t("connection.targets.lastUsed","Last Used"),tooltip:t("connection.targets.lastUsed.tooltip","Most recent plugin-route request routed to this Studio target")})}),e.jsx("th",{children:e.jsx(_,{label:t("connection.targets.lastSeen","Last Seen"),tooltip:t("connection.targets.lastSeen.tooltip","Most recent heartbeat received from this Studio target")})}),e.jsx("th",{children:e.jsx(_,{label:t("connection.targets.version","Version"),tooltip:t("connection.targets.version.tooltip","Installed plugin version reported by Studio")})}),e.jsx("th",{children:e.jsx(_,{label:t("connection.targets.routing","Routing"),tooltip:t("connection.targets.routing.tooltip","Routing priority for requests without a named Studio target")})}),e.jsx("th",{children:e.jsx(_,{label:t("connection.targets.inFlight","In Flight"),tooltip:t("connection.targets.inFlight.tooltip","Active command request currently routed to this Studio target")})})]})}),e.jsx("tbody",{children:N.length>0?N.map(l=>{const Q=l.clientId.slice(0,10),Z=an(l,t);return e.jsxs("tr",{children:[e.jsxs("td",{children:[e.jsx("span",{className:n.monoMuted,title:l.clientId,children:l.targetAlias}),e.jsx(V,{text:t("connection.targets.copyTargetAlias","Copy Studio ID"),children:e.jsx("button",{type:"button",className:n.copyIconButton,"aria-label":t("connection.targets.copyTargetAlias","Copy Studio ID"),onClick:()=>K(l.targetAlias,"target_alias"),children:e.jsx(J,{size:13,"aria-hidden":"true"})})})]}),e.jsx("td",{children:e.jsx("span",{className:n.targetPrimary,children:l.placeName??"-"})}),e.jsxs("td",{children:[l.placeId??"-",l.placeId!==void 0?e.jsx(V,{text:t("connection.targets.copyPlaceId","Copy Place ID"),children:e.jsx("button",{type:"button",className:n.copyIconButton,"aria-label":t("connection.targets.copyPlaceId","Copy Place ID"),onClick:()=>K(String(l.placeId),"place_id"),children:e.jsx(J,{size:13,"aria-hidden":"true"})})}):null]}),e.jsxs("td",{children:[e.jsx("span",{className:n.monoMuted,title:l.clientId,children:Q}),e.jsx(V,{text:t("connection.targets.copyClientId","Copy Connection ID"),children:e.jsx("button",{type:"button",className:n.copyIconButton,"aria-label":t("connection.targets.copyClientId","Copy Connection ID"),onClick:()=>K(l.clientId,"client_id"),children:e.jsx(J,{size:13,"aria-hidden":"true"})})})]}),e.jsx("td",{children:e.jsx(te,{text:Z.tooltip,children:e.jsx("span",{className:`${n.studioStateBadge} ${n[`studioState_${Z.state}`]}`,children:Z.label})})}),e.jsx("td",{children:l.connectionState}),e.jsx("td",{children:l.lastRoutedAt?Y(l.lastRoutedAt,t):"-"}),e.jsx("td",{children:Y(l.lastSeen,t)}),e.jsx("td",{children:l.pluginVersion??"-"}),e.jsx("td",{children:h==="pinned"&&v===l.clientId?e.jsx("span",{className:n.routingBadge,children:t("connection.routing.pinnedBadge","Pinned")}):h==="recentPriority"&&(L==null?void 0:L.clientId)===l.clientId?e.jsx("span",{className:n.routingBadge,children:t("connection.routing.priorityBadge","Priority")}):e.jsx("span",{className:n.monoMuted,children:"-"})}),e.jsx("td",{children:l.inFlightRequestId?l.inFlightRequestId.slice(0,8):"-"})]},l.clientId)}):e.jsx("tr",{children:e.jsx("td",{colSpan:11,className:n.emptyRow,children:t("connection.targets.none","No Studio targets connected. Open Roblox Studio and connect WEPPY Plugin.")})})})]})})]}),e.jsxs("div",{className:`${n.card} ${y?n.disabled:""}`,children:[e.jsxs("div",{className:n.cardHeader,children:[e.jsx("span",{children:t("connection.log.title","Connection Log")}),e.jsx("button",{className:n.clearButton,onClick:()=>{o("dashboard_click_event",{click_target:"connection_clear_log",page:"connection"}),f(!0)},children:t("common.clear","Clear")})]}),e.jsx(Ee,{entries:u})]}),e.jsx(ee,{open:z,title:t("connection.clear.title","Clear connection log?"),message:t("connection.clear.message","This permanently removes the stored connection log for the current project."),cancelLabel:t("common.cancel","Cancel"),confirmLabel:t("common.clear","Clear"),loading:w,onCancel:()=>!w&&f(!1),onConfirm:de}),e.jsx(ee,{open:D,title:t("connection.server.restartTitle","Restart WEPPY Bridge?"),message:t("connection.server.restartMessage","Dashboard and Studio targets will disconnect briefly. In-progress commands may have an unknown result, and active Playtest sessions or pending controls will be cleaned up. A connected MCP Adapter will start a new Bridge automatically."),cancelLabel:t("common.cancel","Cancel"),confirmLabel:t("connection.server.restartConfirm","Restart Bridge"),loading:C==="requesting",onCancel:()=>C!=="requesting"&&m(!1),onConfirm:q}),e.jsx(ee,{open:!!B,title:t("connection.agents.kill.title","Kill agent?"),message:`"${B==null?void 0:B.name}" 프로세스를 강제 종료합니다. 해당 에이전트의 진행 중인 작업이 중단됩니다.`,cancelLabel:t("common.cancel","Cancel"),confirmLabel:t("connection.agents.kill","Kill"),loading:I,onCancel:()=>!I&&W(null),onConfirm:le})]})}export{Sn as Component};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as P,j as e,d as q,i as z,c as k,r as l,C as K,G as J,H as Z,b as U,s as ee,J as te,h as D,N as ne}from"./index-CG4GxcAc.js";import{D as Q,P as oe}from"./PageHeader-Dc41DgFB.js";import{I as T}from"./InfoLabel-CAGC3efT.js";import{s as j}from"./ConfirmModal.module-DJksQHBd.js";import{T as F}from"./TooltipText-C0DmdntK.js";import{s as t,u as ae}from"./useSettings-Cme-nLG9.js";import{C as B}from"./check-DvBWmDvn.js";import{C as _}from"./copy-vqzBh0XB.js";function H(o,s){return e.jsxs("div",{className:j.pathBlock,children:[e.jsx("span",{className:j.pathLabel,children:o}),e.jsx("code",{className:j.pathCode,children:s})]})}function ie(o){const n=/^[A-Z]:\\/i.test(o)||o.includes("\\")?"\\":"/";return`${o.replace(/[\\/]+$/,"")}${n}weppy-project-sync`}function se({open:o,step:s,selectedProjectRoot:n,studioConnected:d,loading:p=!1,errorMessage:h=null,onClose:a,onPick:c,onApply:g}){const{t:r}=P();if(!o)return null;const y=n?ie(n):"";return e.jsx("div",{className:j.backdrop,onClick:p?void 0:a,role:"presentation",children:e.jsxs("div",{className:j.modal,onClick:x=>x.stopPropagation(),role:"dialog","aria-modal":"true","aria-labelledby":"project-root-change-modal-title",children:[e.jsx("h2",{id:"project-root-change-modal-title",className:j.title,children:s==="initial"?r("header.projectRootModal.initial.title","Change project root"):r("header.projectRootModal.confirm.title","Confirm new project root")}),e.jsx("p",{className:j.message,children:s==="initial"?d?r("header.projectRootModal.initial.body.connected","MCP will switch to the new project root and resync current Studio contents into the new target."):r("header.projectRootModal.initial.body.disconnected","MCP will switch to the new project root and use the new folder as the next sync target."):r("header.projectRootModal.confirm.body","Review the selected project folder before applying.")}),e.jsxs("div",{className:j.bodyGrid,children:[s==="initial"?e.jsxs(e.Fragment,{children:[H(r("header.projectRootModal.initial.nextSyncRoot","New sync target after selection"),r("header.projectRootModal.initial.nextSyncRoot.placeholder","<selected project folder>/weppy-project-sync")),e.jsxs("ul",{className:j.warningList,children:[d?e.jsxs(e.Fragment,{children:[e.jsx("li",{children:r("header.projectRootModal.initial.warningStop","Current sync stops immediately.")}),e.jsx("li",{children:r("header.projectRootModal.initial.warningFreshSync","The current Studio contents will be used to build a fresh full sync in the new target.")})]}):e.jsx("li",{children:r("header.projectRootModal.initial.warningDeferredSync","If Studio is not connected, full resync starts the next time the plugin connects.")}),e.jsx("li",{children:r("header.projectRootModal.initial.warningNoMove","Old sync folders are not moved automatically.")})]})]}):e.jsxs(e.Fragment,{children:[H(r("header.projectRootModal.confirm.projectRoot","Selected project folder"),n??""),H(r("header.projectRootModal.confirm.syncRoot","New sync target"),y),e.jsx("p",{className:j.message,children:r("header.projectRootModal.confirm.warningNoMove","Existing sync folders are not moved automatically.")})]}),h?e.jsx("p",{className:`${j.message} ${j.errorMessage}`,children:h}):null]}),e.jsxs("div",{className:j.actions,children:[e.jsx("button",{className:j.cancelButton,onClick:a,disabled:p,children:r("header.projectRootModal.cancel","Cancel")}),s==="initial"?e.jsx("button",{className:j.confirmButton,onClick:c,disabled:p,children:p?"...":r("header.projectRootModal.pick","Choose folder")}):e.jsx("button",{className:j.confirmButton,onClick:g,disabled:p||!n,children:p?"...":r("header.projectRootModal.apply","Apply change")})]})]})})}function W(o,s){if(o&&typeof o=="object"&&"message"in o&&typeof o.message=="string"){const n=o.message.trim();if(n.length>0)return n}return s}function le(){const{level:o,status:s}=q(),{t:n}=P(),{show:d}=z(),{search:p}=k(),h=l.useRef(null),[a,c]=l.useState(null),[g,r]=l.useState(!1),[y,x]=l.useState(null),[b,N]=l.useState(null),[S,u]=l.useState(!1),[f,v]=l.useState(!1),[L,C]=l.useState(null),M=l.useMemo(()=>new URLSearchParams(p).get("section")==="project-root",[p]),w=l.useCallback(async()=>{if(o==="disconnected"){c(null),r(!1);return}r(!1);try{const m=await K();c(m)}catch{c(null),r(!0)}},[o]);l.useEffect(()=>{w()},[w,s==null?void 0:s.connectedClients,s==null?void 0:s.sessionId]),l.useEffect(()=>{var m,E,V;M&&((E=(m=h.current)==null?void 0:m.scrollIntoView)==null||E.call(m,{block:"start",behavior:"smooth"}),(V=h.current)==null||V.focus())},[M]);const R=(m=!1)=>{!m&&(S||f)||(x(null),N(null),C(null))},i=()=>{o==="disconnected"||!a||(C(null),N(null),x("initial"))},I=async()=>{u(!0),C(null);try{const m=await Z();if(m.cancelled||!m.projectRoot){R(!0);return}N(m.projectRoot),x("confirm")}catch(m){C(W(m,n("header.projectRootModal.error","Failed to change project root")))}finally{u(!1)}},A=async()=>{if(b){v(!0),C(null);try{const m=await J(b);c(m),r(!1),R(!0)}catch(m){const E=W(m,n("header.projectRootModal.error","Failed to change project root"));C(E),d(E,"error")}finally{v(!1)}}},$=g?n("controls.projectRoot.unavailable","Project root unavailable"):n("common.loading","Loading..."),X=o==="disconnected"||!a;return e.jsxs(e.Fragment,{children:[e.jsxs("div",{id:"controls-project-root",ref:h,tabIndex:-1,className:t.card,children:[e.jsxs("div",{className:t.cardHeader,children:[e.jsx(T,{label:n("controls.projectRoot.title","Project Root"),tooltip:n("controls.projectRoot.title.tooltip","Authoritative project root and sync target used by MCP.")}),e.jsx(F,{text:n("controls.projectRoot.live.tooltip","Changing this updates MCP runtime state immediately after confirmation."),children:e.jsx("span",{className:`${t.headerBadge} ${t.headerBadgeLive}`,children:n("settings.general.liveApply","Live Apply")})})]}),e.jsxs("dl",{className:t.controlGrid,children:[e.jsx("dt",{children:n("controls.projectRoot.projectRoot","Project Root")}),e.jsx("dd",{children:(a==null?void 0:a.projectRoot)??$}),e.jsx("dt",{children:n("controls.projectRoot.syncRoot","Sync Root")}),e.jsx("dd",{children:(a==null?void 0:a.projectSyncRoot)??$})]}),e.jsx("p",{className:t.controlHint,children:n("controls.projectRoot.hint","Use this only when MCP should write sync data under a different project folder. Existing sync folders are not moved automatically.")}),e.jsx("button",{type:"button",className:t.actionBtn,disabled:X,onClick:i,children:n("header.changeProjectRoot","Change Project Root")})]}),e.jsx(se,{open:y!==null,step:y??"initial",selectedProjectRoot:b,studioConnected:o==="studioConnected",loading:S||f,errorMessage:L,onClose:R,onPick:I,onApply:A})]})}function ce(o){if(!o)return null;const s=o.placeName?o.placeId!==void 0?`${o.placeName} · ${o.placeId}`:o.placeName:o.placeId!==void 0?String(o.placeId):null;return s?`${o.targetAlias} · ${s}`:o.targetAlias}function G(o,s){const n=Math.max(0,Math.floor((Date.now()-o)/1e3));return n<60?`${n}${s("connection.time.secondsAgo","s ago")}`:n<3600?`${Math.floor(n/60)}${s("connection.time.minutesAgo","m ago")}`:`${Math.floor(n/3600)}${s("connection.time.hoursAgo","h ago")}`}function re(){const{status:o,level:s}=q(),{t:n}=P(),{show:d}=z(),{search:p}=k(),h=l.useRef(null),a=l.useRef(null),[c,g]=l.useState(null),[r,y]=l.useState(null),[x,b]=l.useState("idle"),N=l.useMemo(()=>new URLSearchParams(p).get("section")==="studio-routing",[p]),S=l.useCallback(async()=>{if(s==="disconnected"){g(null);return}try{const i=await U.get("/api/dashboard/studio-routing");g(i)}catch{g(null)}},[s]);l.useEffect(()=>{S()},[S,o==null?void 0:o.connectedClients,o==null?void 0:o.sessionId]),l.useEffect(()=>{var i,I,A;N&&((I=(i=h.current)==null?void 0:i.scrollIntoView)==null||I.call(i,{block:"start",behavior:"smooth"}),(A=h.current)==null||A.focus())},[N]),l.useEffect(()=>()=>{a.current&&clearTimeout(a.current)},[]);const u=(c==null?void 0:c.studioRoutingMode)??(o==null?void 0:o.studioRoutingMode)??"recentPriority",f=(c==null?void 0:c.pinnedTargetClientId)??(o==null?void 0:o.pinnedTargetClientId)??null,v=ee((c==null?void 0:c.targets)??(o==null?void 0:o.pluginClients)??[],u,f),L=(c==null?void 0:c.priorityTarget)??te(v,u,f),C=ce(L),M=new Set(v.filter(i=>i.placeId!==void 0).map(i=>i.placeId).filter((i,I,A)=>A.filter($=>$===i).length>1)),w=async i=>{y(i.studioRoutingMode==="pinned"?i.pinnedTargetClientId??"pinned":"recentPriority"),b("idle"),a.current&&(clearTimeout(a.current),a.current=null);try{const I=await U.patch("/api/dashboard/studio-routing",i);g(I),b("applied"),a.current=setTimeout(()=>{b("idle"),a.current=null},2e3)}catch{b("failed"),d(n("connection.routing.updateFailed","Failed to update routing target"),"error")}finally{y(null)}},R=async i=>{try{await navigator.clipboard.writeText(i),d(n("connection.targets.copied","Copied value"),"success")}catch{d(n("connection.targets.copyFailed","Failed to copy value"),"error")}};return e.jsxs("div",{id:"controls-studio-routing",ref:h,tabIndex:-1,className:t.card,children:[e.jsxs("div",{className:t.cardHeader,children:[e.jsxs("div",{className:t.cardHeaderTitleGroup,children:[e.jsx("span",{children:n("controls.studioRouting.title","Studio Routing")}),e.jsx(Q,{topicId:"studioRouting",variant:"field",tooltip:n("controls.studioRouting.helpButton","How does it work?"),triggerClassName:`${t.cardHelpButton} ${t.touchTarget44}`})]}),e.jsx("span",{className:`${t.headerBadge} ${t.headerBadgeLive}`,children:n("settings.general.liveApply","Live Apply")})]}),e.jsxs("div",{className:t.routingOverview,children:[e.jsxs("div",{className:t.routingOverviewCopy,children:[e.jsx("span",{className:t.routingEyebrow,children:n("controls.studioRouting.priorityTitle","Priority for requests without a named Studio target")}),e.jsx("strong",{children:u==="pinned"?n("connection.routing.pinned","Manual: Pinned Studio"):n("connection.routing.recentPriority","Automatic: Recent priority")}),e.jsx("p",{children:n("controls.studioRouting.priorityDescription","Explicit Studio ID, Connection ID, or Place ID requests bypass this priority setting and route to the named Studio.")})]}),e.jsxs("div",{className:t.priorityTargetSummary,children:[e.jsx("span",{children:n("controls.studioRouting.state.currentTarget","Current priority target")}),e.jsx("strong",{children:C??n("controls.studioRouting.noPriorityTarget","No connected Studio target")}),e.jsx("span",{className:`${t.savedIndicator} ${t.routingFeedback} ${x==="failed"?t.savedIndicatorFailed:""} ${r===null&&x==="idle"?t.savedIndicatorHidden:""}`,"aria-live":"polite","data-testid":"studio-routing-save-feedback",children:r!==null?n("controls.studioRouting.saving","Applying…"):x==="applied"?n("controls.studioRouting.applied","Applied"):x==="failed"?n("controls.studioRouting.failed","Failed to apply"):null})]})]}),e.jsxs("div",{className:t.studioRoutingChoiceControl,role:"group","aria-label":n("connection.routing.priorityControl","Priority mode for requests without a named Studio target"),children:[e.jsxs("button",{type:"button",className:u==="recentPriority"?t.segmentActive:t.segment,disabled:r!==null,"aria-pressed":u==="recentPriority","aria-label":n("controls.studioRouting.mode.auto","Automatic"),onClick:()=>w({studioRoutingMode:"recentPriority"}),children:[e.jsx("span",{className:t.segmentIndicator,"aria-hidden":"true",children:u==="recentPriority"?e.jsx(B,{size:16}):null}),e.jsxs("span",{className:t.segmentCopy,children:[e.jsx("span",{className:t.segmentLabel,children:n("connection.routing.recentPriority","Automatic: Recent priority")}),e.jsx("small",{className:t.segmentDescription,children:n("controls.studioRouting.help.auto","Automatic uses the highest-priority active Studio, based on recent routed commands and connection order.")})]})]}),e.jsxs("button",{type:"button",className:u==="pinned"?t.segmentActive:t.segment,disabled:!v.length||r!==null,"aria-pressed":u==="pinned","aria-label":n("controls.studioRouting.mode.pinned","Studio fixed"),onClick:()=>w({studioRoutingMode:"pinned"}),children:[e.jsx("span",{className:t.segmentIndicator,"aria-hidden":"true",children:u==="pinned"?e.jsx(B,{size:16}):null}),e.jsxs("span",{className:t.segmentCopy,children:[e.jsx("span",{className:t.segmentLabel,children:n("connection.routing.pinned","Manual: Pinned Studio")}),e.jsx("small",{className:t.segmentDescription,children:n("controls.studioRouting.help.pinned","Studio fixed uses the selected Studio unless the request names a Studio ID, Connection ID, or Place ID.")})]})]})]}),v.length?null:e.jsx("p",{className:t.routingDisabledReason,children:n("controls.studioRouting.pinnedUnavailable","Connect a Studio target to use Studio fixed mode.")}),M.size>0?e.jsx("p",{className:t.routingWarning,children:n("controls.studioRouting.duplicatePlaceWarning","More than one connected Studio window has the same Place ID. Ask the AI agent to use Studio ID for that place.")}):null,e.jsx("div",{className:t.tableWrap,role:u==="pinned"?"radiogroup":void 0,"aria-label":u==="pinned"?n("controls.studioRouting.targetGroupLabel","Studio fixed target"):void 0,children:e.jsxs("table",{className:`${t.table} ${t.routingTargetsTable}`,children:[e.jsxs("colgroup",{children:[e.jsx("col",{className:t.routingActionColumn}),e.jsx("col",{span:6})]}),e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:n("connection.targets.routing","Routing")}),e.jsx("th",{children:n("connection.targets.target","Studio ID")}),e.jsx("th",{children:n("connection.targets.place","Place")}),e.jsx("th",{children:n("connection.targets.placeId","Place ID")}),e.jsx("th",{children:n("connection.targets.lastUsed","Last Used")}),e.jsx("th",{children:n("connection.targets.lastSeen","Last Seen")}),e.jsx("th",{children:n("connection.targets.clientId","Connection ID")})]})}),e.jsx("tbody",{children:v.length>0?v.map(i=>e.jsxs("tr",{children:[e.jsx("td",{children:e.jsx("div",{className:t.routingActionSlot,children:u==="pinned"?e.jsxs("button",{type:"button",role:"radio","aria-checked":f===i.clientId,"aria-label":`${n("controls.studioRouting.selectTarget","Select fixed Studio")}: ${i.targetAlias}`,className:`${t.routingTargetRadio} ${f===i.clientId?t.routingTargetRadioActive:""}`,disabled:r!==null,onClick:()=>{f!==i.clientId&&w({studioRoutingMode:"pinned",pinnedTargetClientId:i.clientId})},children:[e.jsx("span",{className:t.routingRadioIndicator,"aria-hidden":"true",children:f===i.clientId?e.jsx(B,{size:12}):null}),e.jsx("span",{children:f===i.clientId?n("connection.routing.pinnedBadge","Pinned"):n("controls.studioRouting.select","Select")})]}):(L==null?void 0:L.clientId)===i.clientId?e.jsx("span",{className:t.routingBadge,children:n("connection.routing.priorityBadge","Priority")}):null})}),e.jsxs("td",{children:[e.jsx("span",{className:t.monoMuted,title:i.clientId,children:i.targetAlias}),e.jsx(D,{text:n("connection.targets.copyTargetAlias","Copy Studio ID"),children:e.jsx("button",{type:"button",className:t.copyIconButton,"aria-label":n("connection.targets.copyTargetAlias","Copy Studio ID"),onClick:()=>R(i.targetAlias),children:e.jsx(_,{size:13,"aria-hidden":"true"})})})]}),e.jsx("td",{children:i.placeName??"-"}),e.jsxs("td",{children:[i.placeId??"-",i.placeId!==void 0?e.jsx(D,{text:n("connection.targets.copyPlaceId","Copy Place ID"),children:e.jsx("button",{type:"button",className:t.copyIconButton,"aria-label":n("connection.targets.copyPlaceId","Copy Place ID"),onClick:()=>R(String(i.placeId)),children:e.jsx(_,{size:13,"aria-hidden":"true"})})}):null]}),e.jsx("td",{children:i.lastRoutedAt?G(i.lastRoutedAt,n):"-"}),e.jsx("td",{children:G(i.lastSeen,n)}),e.jsxs("td",{children:[e.jsx("span",{className:t.monoMuted,title:i.clientId,children:i.clientId.slice(0,10)}),e.jsx(D,{text:n("connection.targets.copyClientId","Copy Connection ID"),children:e.jsx("button",{type:"button",className:t.copyIconButton,"aria-label":n("connection.targets.copyClientId","Copy Connection ID"),onClick:()=>R(i.clientId),children:e.jsx(_,{size:13,"aria-hidden":"true"})})})]})]},i.clientId)):e.jsx("tr",{children:e.jsx("td",{colSpan:7,className:t.emptyRow,children:n("connection.targets.none","No Studio targets connected. Open Roblox Studio and connect WEPPY Plugin.")})})})]})})]})}const Y=["debug","info","warn","error"];function O({checked:o,onChange:s,testId:n,ariaLabel:d}){return e.jsxs("label",{className:t.toggleSwitch,"data-testid":n,children:[e.jsx("input",{type:"checkbox",className:t.toggleInput,checked:o,"aria-label":d,onChange:p=>s(p.target.checked)}),e.jsx("span",{className:t.toggleTrack,"aria-hidden":"true",children:e.jsx("span",{className:t.toggleThumb})})]})}function de({settings:o,updateHotSetting:s}){const{t:n}=P(),[d,p]=l.useState(null),h=l.useCallback(async(a,c)=>{try{await s(a,c),p(a),setTimeout(()=>p(g=>g===a?null:g),2e3)}catch{p(g=>g===a?null:g)}},[s]);return e.jsxs("div",{className:t.card,children:[e.jsxs("div",{className:t.cardHeader,children:[e.jsx(T,{label:n("settings.general.title","General Settings"),tooltip:n("settings.general.title.tooltip","Hot settings that apply immediately when changed.")}),e.jsx(F,{text:n("settings.general.liveApply.tooltip","Changes in this section are applied immediately without a separate save button."),children:e.jsx("span",{className:`${t.headerBadge} ${t.headerBadgeLive}`,children:n("settings.general.liveApply","Live Apply")})})]}),o?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:t.settingRow,children:[e.jsx("span",{className:t.settingLabel,children:e.jsx(T,{label:n("settings.general.logLevel","Log Level"),tooltip:n("settings.general.logLevel.tooltip","Sets how much detail WEPPY Dashboard writes to its logs.")})}),e.jsxs("div",{className:t.settingControl,children:[e.jsx("select",{className:t.select,value:o.hot.LOG_LEVEL,onChange:a=>{const c=Y.find(g=>g===a.target.value);c&&h("LOG_LEVEL",c)},children:Y.map(a=>e.jsx("option",{value:a,children:a},a))}),d==="LOG_LEVEL"&&e.jsx("span",{className:t.savedIndicator,children:n("settings.general.applied")})]})]}),e.jsxs("div",{className:t.settingRow,children:[e.jsx("span",{className:t.settingLabel,children:e.jsx(T,{label:n("settings.general.localHistory","Tool History Recording"),tooltip:n("settings.general.localHistory.tooltip","Stores local tool execution history for the WEPPY Dashboard history views.")})}),e.jsxs("div",{className:t.settingControl,children:[e.jsx("span",{className:`${t.savedIndicator} ${d==="ENABLE_LOCAL_HISTORY"?"":t.savedIndicatorHidden}`,children:n("settings.general.applied","Applied")}),e.jsx(O,{checked:o.hot.ENABLE_LOCAL_HISTORY,ariaLabel:n("settings.general.localHistory","Tool History Recording"),testId:"settings-toggle-enable-local-history",onChange:a=>h("ENABLE_LOCAL_HISTORY",a)})]})]}),e.jsxs("div",{className:t.settingRow,children:[e.jsx("span",{className:t.settingLabel,children:e.jsx(T,{label:n("settings.general.localStatistics","Tool Statistics Collection"),tooltip:n("settings.general.localStatistics.tooltip","Aggregates local usage statistics for WEPPY Dashboard reporting.")})}),e.jsxs("div",{className:t.settingControl,children:[e.jsx("span",{className:`${t.savedIndicator} ${d==="ENABLE_LOCAL_STATISTICS"?"":t.savedIndicatorHidden}`,children:n("settings.general.applied","Applied")}),e.jsx(O,{checked:o.hot.ENABLE_LOCAL_STATISTICS,ariaLabel:n("settings.general.localStatistics","Tool Statistics Collection"),testId:"settings-toggle-enable-local-statistics",onChange:a=>h("ENABLE_LOCAL_STATISTICS",a)})]})]}),e.jsxs("div",{className:t.settingRow,children:[e.jsx("span",{className:t.settingLabel,children:e.jsx(T,{label:n("settings.general.contextCapture","Context Capture"),tooltip:n("settings.general.contextCapture.tooltip","When enabled, WEPPY Dashboard records structured execution context for changelog and playtest views.")})}),e.jsxs("div",{className:t.settingControl,children:[e.jsx("span",{className:`${t.savedIndicator} ${d==="ENABLE_CONTEXT_CAPTURE"?"":t.savedIndicatorHidden}`,children:n("settings.general.applied","Applied")}),e.jsx(O,{checked:o.hot.ENABLE_CONTEXT_CAPTURE,ariaLabel:n("settings.general.contextCapture","Context Capture"),testId:"settings-toggle-enable-context-capture",onChange:a=>h("ENABLE_CONTEXT_CAPTURE",a)})]})]}),e.jsxs("div",{className:t.settingRow,children:[e.jsx("span",{className:t.settingLabel,children:e.jsx(T,{label:n("settings.general.requestTimeout","Action Timeout"),tooltip:n("settings.general.requestTimeout.tooltip","Maximum time WEPPY Dashboard waits for an action before it fails.")})}),e.jsxs("div",{className:t.settingControl,children:[e.jsx("input",{type:"number",className:t.numberInput,value:o.hot.REQUEST_TIMEOUT,min:1e3,max:12e4,step:1e3,onChange:a=>{const c=parseInt(a.target.value,10);isNaN(c)||h("REQUEST_TIMEOUT",c)}}),e.jsx(F,{text:n("settings.general.requestTimeout.unit.tooltip","Action timeout is measured in milliseconds."),children:e.jsx("span",{className:t.unit,children:n("settings.general.requestTimeout.unit","ms")})}),d==="REQUEST_TIMEOUT"&&e.jsx("span",{className:t.savedIndicator,children:n("settings.general.applied","Applied")})]})]})]}):e.jsx("div",{className:t.loading,children:n("settings.unavailable")})]})}function ue({enabled:o,saving:s,onChange:n}){const{t:d}=P(),{search:p}=k(),h=l.useRef(null),a=l.useRef(null),c=l.useId(),[g,r]=l.useState(!1),[y,x]=l.useState("idle"),b=l.useMemo(()=>new URLSearchParams(p).get("section")==="luau-validation",[p]),N=s||g;l.useEffect(()=>{var u,f,v;b&&((f=(u=h.current)==null?void 0:u.scrollIntoView)==null||f.call(u,{block:"start",behavior:"smooth"}),(v=h.current)==null||v.focus())},[b]),l.useEffect(()=>()=>{a.current&&clearTimeout(a.current)},[]);const S=l.useCallback(async u=>{r(!0),x("idle"),a.current&&(clearTimeout(a.current),a.current=null);try{await n(u),x("applied"),a.current=setTimeout(()=>{x("idle"),a.current=null},2e3)}catch{x("failed")}finally{r(!1)}},[n]);return e.jsxs("div",{id:"controls-luau-validation",ref:h,tabIndex:-1,className:`${t.card} ${t.validationCard}`,"data-testid":"luau-syntax-validation-card",children:[e.jsxs("div",{className:t.cardHeader,children:[e.jsxs("div",{className:t.cardHeaderTitleGroup,children:[e.jsx("span",{children:d("controls.luauValidation.title","Luau Syntax Validation")}),e.jsx(Q,{topicId:"luauValidation",variant:"field",tooltip:d("controls.luauValidation.helpButton","How does it work?"),triggerClassName:`${t.cardHelpButton} ${t.touchTarget44}`})]}),e.jsx("span",{className:`${t.headerBadge} ${t.headerBadgeLive}`,children:d("settings.general.liveApply","Live Apply")})]}),e.jsxs("div",{className:t.validationSettingRow,children:[e.jsxs("div",{className:t.validationSettingCopy,children:[e.jsx("span",{id:c,className:t.validationSettingLabel,children:d("controls.luauValidation.settingLabel","Check automatically after Script edits")}),e.jsx("span",{className:t.validationSettingStatus,children:o?d("controls.luauValidation.state.on","Current: On"):d("controls.luauValidation.state.off","Current: Off")})]}),e.jsxs("div",{className:t.validationPolicyControl,children:[e.jsx("span",{className:`${t.savedIndicator} ${y==="failed"?t.savedIndicatorFailed:""} ${!N&&y==="idle"?t.savedIndicatorHidden:""}`,"data-testid":"luau-validation-save-feedback","aria-live":"polite",children:N?d("controls.luauValidation.saving","Saving…"):y==="applied"?d("controls.luauValidation.applied","Applied"):y==="failed"?d("controls.luauValidation.failed","Failed to apply"):null}),e.jsxs("label",{className:`${t.toggleSwitch} ${t.validationToggleTarget}`,"data-testid":"luau-validation-toggle",children:[e.jsx("input",{type:"checkbox",role:"switch",className:t.toggleInput,checked:o,disabled:N,"aria-labelledby":c,onChange:u=>{S(u.target.checked)}}),e.jsx("span",{className:t.toggleTrack,"aria-hidden":"true",children:e.jsx("span",{className:t.toggleThumb})})]})]})]})]})}function ve(){const{t:o}=P(),{search:s}=k(),{settings:n,updateHotSetting:d,saving:p,loading:h}=ae();return l.useMemo(()=>new URLSearchParams(s).get("section"),[s])==="license"?e.jsx(ne,{to:"/settings?section=license",replace:!0}):h?e.jsx("div",{className:t.page,children:e.jsx("div",{className:t.loading,children:o("common.loading")})}):e.jsxs("div",{className:t.page,children:[e.jsx(oe,{title:o("page.controls.title","Controls"),description:o("page.controls.description","Manage project root, Studio routing, and MCP live settings."),helpTopicId:"controls"}),e.jsx(le,{}),e.jsx(re,{}),e.jsx(ue,{enabled:(n==null?void 0:n.hot.SCRIPT_WRITE_VALIDATION_ENABLED)??!1,saving:p,onChange:c=>d("SCRIPT_WRITE_VALIDATION_ENABLED",c)}),e.jsx(de,{settings:n,updateHotSetting:d})]})}export{ve as Component};
|
|
1
|
+
import{u as P,j as e,d as q,k as z,c as k,r as l,J as X,K as J,N as Z,b as U,s as ee,O as te,i as D,Q as ne}from"./index-uP4eoQi-.js";import{D as Q,P as oe}from"./PageHeader-_z4Dtkbg.js";import{I as T}from"./InfoLabel-DAd1I756.js";import{s as j}from"./ConfirmModal.module-DJksQHBd.js";import{T as F}from"./TooltipText-NA7u0bu6.js";import{s as t,u as ae}from"./useSettings-kOu_k9zT.js";import{C as B}from"./check-GVlTbKVy.js";import{C as _}from"./copy-DVGVC27v.js";function H(o,s){return e.jsxs("div",{className:j.pathBlock,children:[e.jsx("span",{className:j.pathLabel,children:o}),e.jsx("code",{className:j.pathCode,children:s})]})}function ie(o){const n=/^[A-Z]:\\/i.test(o)||o.includes("\\")?"\\":"/";return`${o.replace(/[\\/]+$/,"")}${n}weppy-project-sync`}function se({open:o,step:s,selectedProjectRoot:n,studioConnected:d,loading:p=!1,errorMessage:h=null,onClose:a,onPick:c,onApply:g}){const{t:r}=P();if(!o)return null;const y=n?ie(n):"";return e.jsx("div",{className:j.backdrop,onClick:p?void 0:a,role:"presentation",children:e.jsxs("div",{className:j.modal,onClick:x=>x.stopPropagation(),role:"dialog","aria-modal":"true","aria-labelledby":"project-root-change-modal-title",children:[e.jsx("h2",{id:"project-root-change-modal-title",className:j.title,children:s==="initial"?r("header.projectRootModal.initial.title","Change project root"):r("header.projectRootModal.confirm.title","Confirm new project root")}),e.jsx("p",{className:j.message,children:s==="initial"?d?r("header.projectRootModal.initial.body.connected","MCP will switch to the new project root and resync current Studio contents into the new target."):r("header.projectRootModal.initial.body.disconnected","MCP will switch to the new project root and use the new folder as the next sync target."):r("header.projectRootModal.confirm.body","Review the selected project folder before applying.")}),e.jsxs("div",{className:j.bodyGrid,children:[s==="initial"?e.jsxs(e.Fragment,{children:[H(r("header.projectRootModal.initial.nextSyncRoot","New sync target after selection"),r("header.projectRootModal.initial.nextSyncRoot.placeholder","<selected project folder>/weppy-project-sync")),e.jsxs("ul",{className:j.warningList,children:[d?e.jsxs(e.Fragment,{children:[e.jsx("li",{children:r("header.projectRootModal.initial.warningStop","Current sync stops immediately.")}),e.jsx("li",{children:r("header.projectRootModal.initial.warningFreshSync","The current Studio contents will be used to build a fresh full sync in the new target.")})]}):e.jsx("li",{children:r("header.projectRootModal.initial.warningDeferredSync","If Studio is not connected, full resync starts the next time the plugin connects.")}),e.jsx("li",{children:r("header.projectRootModal.initial.warningNoMove","Old sync folders are not moved automatically.")})]})]}):e.jsxs(e.Fragment,{children:[H(r("header.projectRootModal.confirm.projectRoot","Selected project folder"),n??""),H(r("header.projectRootModal.confirm.syncRoot","New sync target"),y),e.jsx("p",{className:j.message,children:r("header.projectRootModal.confirm.warningNoMove","Existing sync folders are not moved automatically.")})]}),h?e.jsx("p",{className:`${j.message} ${j.errorMessage}`,children:h}):null]}),e.jsxs("div",{className:j.actions,children:[e.jsx("button",{className:j.cancelButton,onClick:a,disabled:p,children:r("header.projectRootModal.cancel","Cancel")}),s==="initial"?e.jsx("button",{className:j.confirmButton,onClick:c,disabled:p,children:p?"...":r("header.projectRootModal.pick","Choose folder")}):e.jsx("button",{className:j.confirmButton,onClick:g,disabled:p||!n,children:p?"...":r("header.projectRootModal.apply","Apply change")})]})]})})}function W(o,s){if(o&&typeof o=="object"&&"message"in o&&typeof o.message=="string"){const n=o.message.trim();if(n.length>0)return n}return s}function le(){const{level:o,status:s}=q(),{t:n}=P(),{show:d}=z(),{search:p}=k(),h=l.useRef(null),[a,c]=l.useState(null),[g,r]=l.useState(!1),[y,x]=l.useState(null),[b,N]=l.useState(null),[S,u]=l.useState(!1),[f,v]=l.useState(!1),[L,C]=l.useState(null),M=l.useMemo(()=>new URLSearchParams(p).get("section")==="project-root",[p]),w=l.useCallback(async()=>{if(o==="disconnected"){c(null),r(!1);return}r(!1);try{const m=await X();c(m)}catch{c(null),r(!0)}},[o]);l.useEffect(()=>{w()},[w,s==null?void 0:s.connectedClients,s==null?void 0:s.sessionId]),l.useEffect(()=>{var m,E,V;M&&((E=(m=h.current)==null?void 0:m.scrollIntoView)==null||E.call(m,{block:"start",behavior:"smooth"}),(V=h.current)==null||V.focus())},[M]);const R=(m=!1)=>{!m&&(S||f)||(x(null),N(null),C(null))},i=()=>{o==="disconnected"||!a||(C(null),N(null),x("initial"))},I=async()=>{u(!0),C(null);try{const m=await Z();if(m.cancelled||!m.projectRoot){R(!0);return}N(m.projectRoot),x("confirm")}catch(m){C(W(m,n("header.projectRootModal.error","Failed to change project root")))}finally{u(!1)}},A=async()=>{if(b){v(!0),C(null);try{const m=await J(b);c(m),r(!1),R(!0)}catch(m){const E=W(m,n("header.projectRootModal.error","Failed to change project root"));C(E),d(E,"error")}finally{v(!1)}}},$=g?n("controls.projectRoot.unavailable","Project root unavailable"):n("common.loading","Loading..."),K=o==="disconnected"||!a;return e.jsxs(e.Fragment,{children:[e.jsxs("div",{id:"controls-project-root",ref:h,tabIndex:-1,className:t.card,children:[e.jsxs("div",{className:t.cardHeader,children:[e.jsx(T,{label:n("controls.projectRoot.title","Project Root"),tooltip:n("controls.projectRoot.title.tooltip","Authoritative project root and sync target used by MCP.")}),e.jsx(F,{text:n("controls.projectRoot.live.tooltip","Changing this updates MCP runtime state immediately after confirmation."),children:e.jsx("span",{className:`${t.headerBadge} ${t.headerBadgeLive}`,children:n("settings.general.liveApply","Live Apply")})})]}),e.jsxs("dl",{className:t.controlGrid,children:[e.jsx("dt",{children:n("controls.projectRoot.projectRoot","Project Root")}),e.jsx("dd",{children:(a==null?void 0:a.projectRoot)??$}),e.jsx("dt",{children:n("controls.projectRoot.syncRoot","Sync Root")}),e.jsx("dd",{children:(a==null?void 0:a.projectSyncRoot)??$})]}),e.jsx("p",{className:t.controlHint,children:n("controls.projectRoot.hint","Use this only when MCP should write sync data under a different project folder. Existing sync folders are not moved automatically.")}),e.jsx("button",{type:"button",className:t.actionBtn,disabled:K,onClick:i,children:n("header.changeProjectRoot","Change Project Root")})]}),e.jsx(se,{open:y!==null,step:y??"initial",selectedProjectRoot:b,studioConnected:o==="studioConnected",loading:S||f,errorMessage:L,onClose:R,onPick:I,onApply:A})]})}function ce(o){if(!o)return null;const s=o.placeName?o.placeId!==void 0?`${o.placeName} · ${o.placeId}`:o.placeName:o.placeId!==void 0?String(o.placeId):null;return s?`${o.targetAlias} · ${s}`:o.targetAlias}function G(o,s){const n=Math.max(0,Math.floor((Date.now()-o)/1e3));return n<60?`${n}${s("connection.time.secondsAgo","s ago")}`:n<3600?`${Math.floor(n/60)}${s("connection.time.minutesAgo","m ago")}`:`${Math.floor(n/3600)}${s("connection.time.hoursAgo","h ago")}`}function re(){const{status:o,level:s}=q(),{t:n}=P(),{show:d}=z(),{search:p}=k(),h=l.useRef(null),a=l.useRef(null),[c,g]=l.useState(null),[r,y]=l.useState(null),[x,b]=l.useState("idle"),N=l.useMemo(()=>new URLSearchParams(p).get("section")==="studio-routing",[p]),S=l.useCallback(async()=>{if(s==="disconnected"){g(null);return}try{const i=await U.get("/api/dashboard/studio-routing");g(i)}catch{g(null)}},[s]);l.useEffect(()=>{S()},[S,o==null?void 0:o.connectedClients,o==null?void 0:o.sessionId]),l.useEffect(()=>{var i,I,A;N&&((I=(i=h.current)==null?void 0:i.scrollIntoView)==null||I.call(i,{block:"start",behavior:"smooth"}),(A=h.current)==null||A.focus())},[N]),l.useEffect(()=>()=>{a.current&&clearTimeout(a.current)},[]);const u=(c==null?void 0:c.studioRoutingMode)??(o==null?void 0:o.studioRoutingMode)??"recentPriority",f=(c==null?void 0:c.pinnedTargetClientId)??(o==null?void 0:o.pinnedTargetClientId)??null,v=ee((c==null?void 0:c.targets)??(o==null?void 0:o.pluginClients)??[],u,f),L=(c==null?void 0:c.priorityTarget)??te(v,u,f),C=ce(L),M=new Set(v.filter(i=>i.placeId!==void 0).map(i=>i.placeId).filter((i,I,A)=>A.filter($=>$===i).length>1)),w=async i=>{y(i.studioRoutingMode==="pinned"?i.pinnedTargetClientId??"pinned":"recentPriority"),b("idle"),a.current&&(clearTimeout(a.current),a.current=null);try{const I=await U.patch("/api/dashboard/studio-routing",i);g(I),b("applied"),a.current=setTimeout(()=>{b("idle"),a.current=null},2e3)}catch{b("failed"),d(n("connection.routing.updateFailed","Failed to update routing target"),"error")}finally{y(null)}},R=async i=>{try{await navigator.clipboard.writeText(i),d(n("connection.targets.copied","Copied value"),"success")}catch{d(n("connection.targets.copyFailed","Failed to copy value"),"error")}};return e.jsxs("div",{id:"controls-studio-routing",ref:h,tabIndex:-1,className:t.card,children:[e.jsxs("div",{className:t.cardHeader,children:[e.jsxs("div",{className:t.cardHeaderTitleGroup,children:[e.jsx("span",{children:n("controls.studioRouting.title","Studio Routing")}),e.jsx(Q,{topicId:"studioRouting",variant:"field",tooltip:n("controls.studioRouting.helpButton","How does it work?"),triggerClassName:`${t.cardHelpButton} ${t.touchTarget44}`})]}),e.jsx("span",{className:`${t.headerBadge} ${t.headerBadgeLive}`,children:n("settings.general.liveApply","Live Apply")})]}),e.jsxs("div",{className:t.routingOverview,children:[e.jsxs("div",{className:t.routingOverviewCopy,children:[e.jsx("span",{className:t.routingEyebrow,children:n("controls.studioRouting.priorityTitle","Priority for requests without a named Studio target")}),e.jsx("strong",{children:u==="pinned"?n("connection.routing.pinned","Manual: Pinned Studio"):n("connection.routing.recentPriority","Automatic: Recent priority")}),e.jsx("p",{children:n("controls.studioRouting.priorityDescription","Explicit Studio ID, Connection ID, or Place ID requests bypass this priority setting and route to the named Studio.")})]}),e.jsxs("div",{className:t.priorityTargetSummary,children:[e.jsx("span",{children:n("controls.studioRouting.state.currentTarget","Current priority target")}),e.jsx("strong",{children:C??n("controls.studioRouting.noPriorityTarget","No connected Studio target")}),e.jsx("span",{className:`${t.savedIndicator} ${t.routingFeedback} ${x==="failed"?t.savedIndicatorFailed:""} ${r===null&&x==="idle"?t.savedIndicatorHidden:""}`,"aria-live":"polite","data-testid":"studio-routing-save-feedback",children:r!==null?n("controls.studioRouting.saving","Applying…"):x==="applied"?n("controls.studioRouting.applied","Applied"):x==="failed"?n("controls.studioRouting.failed","Failed to apply"):null})]})]}),e.jsxs("div",{className:t.studioRoutingChoiceControl,role:"group","aria-label":n("connection.routing.priorityControl","Priority mode for requests without a named Studio target"),children:[e.jsxs("button",{type:"button",className:u==="recentPriority"?t.segmentActive:t.segment,disabled:r!==null,"aria-pressed":u==="recentPriority","aria-label":n("controls.studioRouting.mode.auto","Automatic"),onClick:()=>w({studioRoutingMode:"recentPriority"}),children:[e.jsx("span",{className:t.segmentIndicator,"aria-hidden":"true",children:u==="recentPriority"?e.jsx(B,{size:16}):null}),e.jsxs("span",{className:t.segmentCopy,children:[e.jsx("span",{className:t.segmentLabel,children:n("connection.routing.recentPriority","Automatic: Recent priority")}),e.jsx("small",{className:t.segmentDescription,children:n("controls.studioRouting.help.auto","Automatic uses the highest-priority active Studio, based on recent routed commands and connection order.")})]})]}),e.jsxs("button",{type:"button",className:u==="pinned"?t.segmentActive:t.segment,disabled:!v.length||r!==null,"aria-pressed":u==="pinned","aria-label":n("controls.studioRouting.mode.pinned","Studio fixed"),onClick:()=>w({studioRoutingMode:"pinned"}),children:[e.jsx("span",{className:t.segmentIndicator,"aria-hidden":"true",children:u==="pinned"?e.jsx(B,{size:16}):null}),e.jsxs("span",{className:t.segmentCopy,children:[e.jsx("span",{className:t.segmentLabel,children:n("connection.routing.pinned","Manual: Pinned Studio")}),e.jsx("small",{className:t.segmentDescription,children:n("controls.studioRouting.help.pinned","Studio fixed uses the selected Studio unless the request names a Studio ID, Connection ID, or Place ID.")})]})]})]}),v.length?null:e.jsx("p",{className:t.routingDisabledReason,children:n("controls.studioRouting.pinnedUnavailable","Connect a Studio target to use Studio fixed mode.")}),M.size>0?e.jsx("p",{className:t.routingWarning,children:n("controls.studioRouting.duplicatePlaceWarning","More than one connected Studio window has the same Place ID. Ask the AI agent to use Studio ID for that place.")}):null,e.jsx("div",{className:t.tableWrap,role:u==="pinned"?"radiogroup":void 0,"aria-label":u==="pinned"?n("controls.studioRouting.targetGroupLabel","Studio fixed target"):void 0,children:e.jsxs("table",{className:`${t.table} ${t.routingTargetsTable}`,children:[e.jsxs("colgroup",{children:[e.jsx("col",{className:t.routingActionColumn}),e.jsx("col",{span:6})]}),e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:n("connection.targets.routing","Routing")}),e.jsx("th",{children:n("connection.targets.target","Studio ID")}),e.jsx("th",{children:n("connection.targets.place","Place")}),e.jsx("th",{children:n("connection.targets.placeId","Place ID")}),e.jsx("th",{children:n("connection.targets.lastUsed","Last Used")}),e.jsx("th",{children:n("connection.targets.lastSeen","Last Seen")}),e.jsx("th",{children:n("connection.targets.clientId","Connection ID")})]})}),e.jsx("tbody",{children:v.length>0?v.map(i=>e.jsxs("tr",{children:[e.jsx("td",{children:e.jsx("div",{className:t.routingActionSlot,children:u==="pinned"?e.jsxs("button",{type:"button",role:"radio","aria-checked":f===i.clientId,"aria-label":`${n("controls.studioRouting.selectTarget","Select fixed Studio")}: ${i.targetAlias}`,className:`${t.routingTargetRadio} ${f===i.clientId?t.routingTargetRadioActive:""}`,disabled:r!==null,onClick:()=>{f!==i.clientId&&w({studioRoutingMode:"pinned",pinnedTargetClientId:i.clientId})},children:[e.jsx("span",{className:t.routingRadioIndicator,"aria-hidden":"true",children:f===i.clientId?e.jsx(B,{size:12}):null}),e.jsx("span",{children:f===i.clientId?n("connection.routing.pinnedBadge","Pinned"):n("controls.studioRouting.select","Select")})]}):(L==null?void 0:L.clientId)===i.clientId?e.jsx("span",{className:t.routingBadge,children:n("connection.routing.priorityBadge","Priority")}):null})}),e.jsxs("td",{children:[e.jsx("span",{className:t.monoMuted,title:i.clientId,children:i.targetAlias}),e.jsx(D,{text:n("connection.targets.copyTargetAlias","Copy Studio ID"),children:e.jsx("button",{type:"button",className:t.copyIconButton,"aria-label":n("connection.targets.copyTargetAlias","Copy Studio ID"),onClick:()=>R(i.targetAlias),children:e.jsx(_,{size:13,"aria-hidden":"true"})})})]}),e.jsx("td",{children:i.placeName??"-"}),e.jsxs("td",{children:[i.placeId??"-",i.placeId!==void 0?e.jsx(D,{text:n("connection.targets.copyPlaceId","Copy Place ID"),children:e.jsx("button",{type:"button",className:t.copyIconButton,"aria-label":n("connection.targets.copyPlaceId","Copy Place ID"),onClick:()=>R(String(i.placeId)),children:e.jsx(_,{size:13,"aria-hidden":"true"})})}):null]}),e.jsx("td",{children:i.lastRoutedAt?G(i.lastRoutedAt,n):"-"}),e.jsx("td",{children:G(i.lastSeen,n)}),e.jsxs("td",{children:[e.jsx("span",{className:t.monoMuted,title:i.clientId,children:i.clientId.slice(0,10)}),e.jsx(D,{text:n("connection.targets.copyClientId","Copy Connection ID"),children:e.jsx("button",{type:"button",className:t.copyIconButton,"aria-label":n("connection.targets.copyClientId","Copy Connection ID"),onClick:()=>R(i.clientId),children:e.jsx(_,{size:13,"aria-hidden":"true"})})})]})]},i.clientId)):e.jsx("tr",{children:e.jsx("td",{colSpan:7,className:t.emptyRow,children:n("connection.targets.none","No Studio targets connected. Open Roblox Studio and connect WEPPY Plugin.")})})})]})})]})}const Y=["debug","info","warn","error"];function O({checked:o,onChange:s,testId:n,ariaLabel:d}){return e.jsxs("label",{className:t.toggleSwitch,"data-testid":n,children:[e.jsx("input",{type:"checkbox",className:t.toggleInput,checked:o,"aria-label":d,onChange:p=>s(p.target.checked)}),e.jsx("span",{className:t.toggleTrack,"aria-hidden":"true",children:e.jsx("span",{className:t.toggleThumb})})]})}function de({settings:o,updateHotSetting:s}){const{t:n}=P(),[d,p]=l.useState(null),h=l.useCallback(async(a,c)=>{try{await s(a,c),p(a),setTimeout(()=>p(g=>g===a?null:g),2e3)}catch{p(g=>g===a?null:g)}},[s]);return e.jsxs("div",{className:t.card,children:[e.jsxs("div",{className:t.cardHeader,children:[e.jsx(T,{label:n("settings.general.title","General Settings"),tooltip:n("settings.general.title.tooltip","Hot settings that apply immediately when changed.")}),e.jsx(F,{text:n("settings.general.liveApply.tooltip","Changes in this section are applied immediately without a separate save button."),children:e.jsx("span",{className:`${t.headerBadge} ${t.headerBadgeLive}`,children:n("settings.general.liveApply","Live Apply")})})]}),o?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:t.settingRow,children:[e.jsx("span",{className:t.settingLabel,children:e.jsx(T,{label:n("settings.general.logLevel","Log Level"),tooltip:n("settings.general.logLevel.tooltip","Sets how much detail WEPPY Dashboard writes to its logs.")})}),e.jsxs("div",{className:t.settingControl,children:[e.jsx("select",{className:t.select,value:o.hot.LOG_LEVEL,onChange:a=>{const c=Y.find(g=>g===a.target.value);c&&h("LOG_LEVEL",c)},children:Y.map(a=>e.jsx("option",{value:a,children:a},a))}),d==="LOG_LEVEL"&&e.jsx("span",{className:t.savedIndicator,children:n("settings.general.applied")})]})]}),e.jsxs("div",{className:t.settingRow,children:[e.jsx("span",{className:t.settingLabel,children:e.jsx(T,{label:n("settings.general.localHistory","Tool History Recording"),tooltip:n("settings.general.localHistory.tooltip","Stores local tool execution history for the WEPPY Dashboard history views.")})}),e.jsxs("div",{className:t.settingControl,children:[e.jsx("span",{className:`${t.savedIndicator} ${d==="ENABLE_LOCAL_HISTORY"?"":t.savedIndicatorHidden}`,children:n("settings.general.applied","Applied")}),e.jsx(O,{checked:o.hot.ENABLE_LOCAL_HISTORY,ariaLabel:n("settings.general.localHistory","Tool History Recording"),testId:"settings-toggle-enable-local-history",onChange:a=>h("ENABLE_LOCAL_HISTORY",a)})]})]}),e.jsxs("div",{className:t.settingRow,children:[e.jsx("span",{className:t.settingLabel,children:e.jsx(T,{label:n("settings.general.localStatistics","Tool Statistics Collection"),tooltip:n("settings.general.localStatistics.tooltip","Aggregates local usage statistics for WEPPY Dashboard reporting.")})}),e.jsxs("div",{className:t.settingControl,children:[e.jsx("span",{className:`${t.savedIndicator} ${d==="ENABLE_LOCAL_STATISTICS"?"":t.savedIndicatorHidden}`,children:n("settings.general.applied","Applied")}),e.jsx(O,{checked:o.hot.ENABLE_LOCAL_STATISTICS,ariaLabel:n("settings.general.localStatistics","Tool Statistics Collection"),testId:"settings-toggle-enable-local-statistics",onChange:a=>h("ENABLE_LOCAL_STATISTICS",a)})]})]}),e.jsxs("div",{className:t.settingRow,children:[e.jsx("span",{className:t.settingLabel,children:e.jsx(T,{label:n("settings.general.contextCapture","Context Capture"),tooltip:n("settings.general.contextCapture.tooltip","When enabled, WEPPY Dashboard records structured execution context for changelog and playtest views.")})}),e.jsxs("div",{className:t.settingControl,children:[e.jsx("span",{className:`${t.savedIndicator} ${d==="ENABLE_CONTEXT_CAPTURE"?"":t.savedIndicatorHidden}`,children:n("settings.general.applied","Applied")}),e.jsx(O,{checked:o.hot.ENABLE_CONTEXT_CAPTURE,ariaLabel:n("settings.general.contextCapture","Context Capture"),testId:"settings-toggle-enable-context-capture",onChange:a=>h("ENABLE_CONTEXT_CAPTURE",a)})]})]}),e.jsxs("div",{className:t.settingRow,children:[e.jsx("span",{className:t.settingLabel,children:e.jsx(T,{label:n("settings.general.requestTimeout","Action Timeout"),tooltip:n("settings.general.requestTimeout.tooltip","Maximum time WEPPY Dashboard waits for an action before it fails.")})}),e.jsxs("div",{className:t.settingControl,children:[e.jsx("input",{type:"number",className:t.numberInput,value:o.hot.REQUEST_TIMEOUT,min:1e3,max:12e4,step:1e3,onChange:a=>{const c=parseInt(a.target.value,10);isNaN(c)||h("REQUEST_TIMEOUT",c)}}),e.jsx(F,{text:n("settings.general.requestTimeout.unit.tooltip","Action timeout is measured in milliseconds."),children:e.jsx("span",{className:t.unit,children:n("settings.general.requestTimeout.unit","ms")})}),d==="REQUEST_TIMEOUT"&&e.jsx("span",{className:t.savedIndicator,children:n("settings.general.applied","Applied")})]})]})]}):e.jsx("div",{className:t.loading,children:n("settings.unavailable")})]})}function ue({enabled:o,saving:s,onChange:n}){const{t:d}=P(),{search:p}=k(),h=l.useRef(null),a=l.useRef(null),c=l.useId(),[g,r]=l.useState(!1),[y,x]=l.useState("idle"),b=l.useMemo(()=>new URLSearchParams(p).get("section")==="luau-validation",[p]),N=s||g;l.useEffect(()=>{var u,f,v;b&&((f=(u=h.current)==null?void 0:u.scrollIntoView)==null||f.call(u,{block:"start",behavior:"smooth"}),(v=h.current)==null||v.focus())},[b]),l.useEffect(()=>()=>{a.current&&clearTimeout(a.current)},[]);const S=l.useCallback(async u=>{r(!0),x("idle"),a.current&&(clearTimeout(a.current),a.current=null);try{await n(u),x("applied"),a.current=setTimeout(()=>{x("idle"),a.current=null},2e3)}catch{x("failed")}finally{r(!1)}},[n]);return e.jsxs("div",{id:"controls-luau-validation",ref:h,tabIndex:-1,className:`${t.card} ${t.validationCard}`,"data-testid":"luau-syntax-validation-card",children:[e.jsxs("div",{className:t.cardHeader,children:[e.jsxs("div",{className:t.cardHeaderTitleGroup,children:[e.jsx("span",{children:d("controls.luauValidation.title","Luau Syntax Validation")}),e.jsx(Q,{topicId:"luauValidation",variant:"field",tooltip:d("controls.luauValidation.helpButton","How does it work?"),triggerClassName:`${t.cardHelpButton} ${t.touchTarget44}`})]}),e.jsx("span",{className:`${t.headerBadge} ${t.headerBadgeLive}`,children:d("settings.general.liveApply","Live Apply")})]}),e.jsxs("div",{className:t.validationSettingRow,children:[e.jsxs("div",{className:t.validationSettingCopy,children:[e.jsx("span",{id:c,className:t.validationSettingLabel,children:d("controls.luauValidation.settingLabel","Check automatically after Script edits")}),e.jsx("span",{className:t.validationSettingStatus,children:o?d("controls.luauValidation.state.on","Current: On"):d("controls.luauValidation.state.off","Current: Off")})]}),e.jsxs("div",{className:t.validationPolicyControl,children:[e.jsx("span",{className:`${t.savedIndicator} ${y==="failed"?t.savedIndicatorFailed:""} ${!N&&y==="idle"?t.savedIndicatorHidden:""}`,"data-testid":"luau-validation-save-feedback","aria-live":"polite",children:N?d("controls.luauValidation.saving","Saving…"):y==="applied"?d("controls.luauValidation.applied","Applied"):y==="failed"?d("controls.luauValidation.failed","Failed to apply"):null}),e.jsxs("label",{className:`${t.toggleSwitch} ${t.validationToggleTarget}`,"data-testid":"luau-validation-toggle",children:[e.jsx("input",{type:"checkbox",role:"switch",className:t.toggleInput,checked:o,disabled:N,"aria-labelledby":c,onChange:u=>{S(u.target.checked)}}),e.jsx("span",{className:t.toggleTrack,"aria-hidden":"true",children:e.jsx("span",{className:t.toggleThumb})})]})]})]})]})}function ve(){const{t:o}=P(),{search:s}=k(),{settings:n,updateHotSetting:d,saving:p,loading:h}=ae();return l.useMemo(()=>new URLSearchParams(s).get("section"),[s])==="license"?e.jsx(ne,{to:"/settings?section=license",replace:!0}):h?e.jsx("div",{className:t.page,children:e.jsx("div",{className:t.loading,children:o("common.loading")})}):e.jsxs("div",{className:t.page,children:[e.jsx(oe,{title:o("page.controls.title","Controls"),description:o("page.controls.description","Manage project root, Studio routing, and MCP live settings."),helpTopicId:"controls"}),e.jsx(le,{}),e.jsx(re,{}),e.jsx(ue,{enabled:(n==null?void 0:n.hot.SCRIPT_WRITE_VALIDATION_ENABLED)??!1,saving:p,onChange:c=>d("SCRIPT_WRITE_VALIDATION_ENABLED",c)}),e.jsx(de,{settings:n,updateHotSetting:d})]})}export{ve as Component};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{u as _,r as x,j as e}from"./index-
|
|
1
|
+
import{u as _,r as x,j as e}from"./index-uP4eoQi-.js";const N="_container_uv8oc_2",j="_header_uv8oc_10",v="_modeBtn_uv8oc_18",g="_modeBtnActive_uv8oc_33",w="_unifiedView_uv8oc_40",L="_diffLine_uv8oc_46",b="_lineNum_uv8oc_55",C="_lineContent_uv8oc_64",S="_lineAdded_uv8oc_68",V="_lineRemoved_uv8oc_73",B="_lineContext_uv8oc_78",$="_sideBySide_uv8oc_83",A="_sidePane_uv8oc_90",P="_sideLabel_uv8oc_100",R="_sideContent_uv8oc_112",D="_empty_uv8oc_117",s={container:N,header:j,modeBtn:v,modeBtnActive:g,unifiedView:w,diffLine:L,lineNum:b,lineContent:C,lineAdded:S,lineRemoved:V,lineContext:B,sideBySide:$,sidePane:A,sideLabel:P,sideContent:R,empty:D};function k(n,i){const l=n.split(`
|
|
2
2
|
`),d=i.split(`
|
|
3
3
|
`),a=[],f=Math.max(l.length,d.length);let t=0,r=0;for(;(t<l.length||r<d.length)&&(t<l.length&&r<d.length?l[t]===d[r]?(a.push({type:"context",content:l[t],lineNum:r+1}),t++,r++):(a.push({type:"removed",content:l[t],lineNum:t+1}),t++,t<l.length&&l[t]===d[r]?(a.push({type:"added",content:d[r],lineNum:r+1}),r++):r<d.length&&(a.push({type:"added",content:d[r],lineNum:r+1}),r++)):t<l.length?(a.push({type:"removed",content:l[t],lineNum:t+1}),t++):r<d.length&&(a.push({type:"added",content:d[r],lineNum:r+1}),r++),!(a.length>f*3)););return a}function O({before:n,after:i}){const{t:l}=_(),[d,a]=x.useState("unified"),f=typeof n=="string"?n:n!=null?JSON.stringify(n,null,2):"",t=typeof i=="string"?i:i!=null?JSON.stringify(i,null,2):"",r=x.useMemo(()=>k(f,t),[f,t]);if(!f&&!t)return e.jsx("div",{className:s.container,children:e.jsx("div",{className:s.empty,children:l("changelog.diff.empty","No diff available")})});if(!f&&t){const c=t.split(`
|
|
4
4
|
`);return e.jsx("div",{className:s.container,children:e.jsx("div",{className:s.unifiedView,children:c.map((u,m)=>e.jsxs("div",{className:`${s.diffLine} ${s.lineAdded}`,children:[e.jsx("span",{className:s.lineNum,children:m+1}),e.jsxs("span",{className:s.lineContent,children:["+ ",u]})]},m))})})}return e.jsxs("div",{className:s.container,children:[e.jsxs("div",{className:s.header,children:[e.jsx("button",{className:`${s.modeBtn} ${d==="unified"?s.modeBtnActive:""}`,onClick:()=>a("unified"),children:l("changelog.diff.unified","Unified")}),e.jsx("button",{className:`${s.modeBtn} ${d==="side-by-side"?s.modeBtnActive:""}`,onClick:()=>a("side-by-side"),children:l("changelog.diff.sideBySide","Side by Side")})]}),d==="unified"?e.jsx("div",{className:s.unifiedView,children:r.map((c,u)=>e.jsxs("div",{className:`${s.diffLine} ${c.type==="added"?s.lineAdded:c.type==="removed"?s.lineRemoved:s.lineContext}`,children:[e.jsx("span",{className:s.lineNum,children:c.lineNum??""}),e.jsxs("span",{className:s.lineContent,children:[c.type==="added"?"+ ":c.type==="removed"?"- ":" ",c.content]})]},u))}):e.jsxs("div",{className:s.sideBySide,children:[e.jsxs("div",{className:s.sidePane,children:[e.jsx("div",{className:s.sideLabel,children:l("changelog.diff.before","Before")}),e.jsx("div",{className:s.sideContent,children:f.split(`
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as r,i as e}from"./index-uP4eoQi-.js";function n({label:t,tooltip:o}){return r.jsx(e,{text:o,children:t})}export{n as I};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as s,u as R,r as h,d as L,e as F,b as M,D as V}from"./index-uP4eoQi-.js";import{I as A}from"./InfoLabel-DAd1I756.js";import{P as U}from"./PageHeader-_z4Dtkbg.js";import{u as z,f as O,S as X}from"./useLiveUptime-BGDr-4gk.js";import{T as q}from"./TooltipText-NA7u0bu6.js";import{G as J}from"./GameChangeDetail-DJ0xywJq.js";const K="_page_amwos_2",Q="_card_amwos_10",W="_cardHeader_amwos_17",Y="_disconnectCard_amwos_28",Z="_disconnectIcon_amwos_36",ee="_disconnectTitle_amwos_41",se="_disconnectMessage_amwos_48",te="_reconnectGuide_amwos_55",ne="_guideStep_amwos_64",ie="_stepNumber_amwos_72",ae="_reconnectIndicator_amwos_88",ce="_reconnectDot_amwos_98",re="_pulse_amwos_1",oe="_disconnectActions_amwos_112",le="_btn_amwos_118",de="_btnSecondary_amwos_134",me="_metricRow_amwos_152",ue="_metricGrid_amwos_158",ve="_metricCard_amwos_164",ge="_metric_ok_amwos_174",_e="_metric_warn_amwos_179",he="_metric_error_amwos_184",pe="_metricHeader_amwos_189",we="_metricIcon_amwos_200",fe="_metricTitle_amwos_204",xe="_metricValue_amwos_208",Ce="_metricSubtitle_amwos_215",je="_guideCard_amwos_225",Ne="_guideTitle_amwos_232",ye="_checklist_amwos_239",Te="_feedEmpty_amwos_263",Se="_feedList_amwos_270",Ie="_feedItem_amwos_278",be="_feedTime_amwos_291",ke="_feedIcon_amwos_298",Me="_feedSummary_amwos_304",De="_feedText_amwos_313",Be="_feedContext_amwos_321",He="_feedItemClickable_amwos_330",Ee="_feedChevron_amwos_338",Pe="_feedDetail_amwos_347",$e="_feedDetailPre_amwos_356",Re="_feedDetailText_amwos_365",Ge="_changelogSummary_amwos_372",Le="_changeTag_amwos_381",Fe="_tierBar_amwos_393",Ve="_tierBarTrack_amwos_399",Ae="_tierBarFillBasic_amwos_407",Ue="_tierBarFillPro_amwos_412",ze="_tierLabels_amwos_417",t={page:K,card:Q,cardHeader:W,disconnectCard:Y,disconnectIcon:Z,disconnectTitle:ee,disconnectMessage:se,reconnectGuide:te,guideStep:ne,stepNumber:ie,reconnectIndicator:ae,reconnectDot:ce,pulse:re,disconnectActions:oe,btn:le,btnSecondary:de,metricRow:me,metricGrid:ue,metricCard:ve,metric_ok:ge,metric_warn:_e,metric_error:he,metricHeader:pe,metricIcon:we,metricTitle:fe,metricValue:xe,metricSubtitle:Ce,guideCard:je,guideTitle:Ne,checklist:ye,feedEmpty:Te,feedList:Se,feedItem:Ie,feedTime:be,feedIcon:ke,feedSummary:Me,feedText:De,feedContext:Be,feedItemClickable:He,feedChevron:Ee,feedDetail:Pe,feedDetailPre:$e,feedDetailText:Re,changelogSummary:Ge,changeTag:Le,tierBar:Fe,tierBarTrack:Ve,tierBarFillBasic:Ae,tierBarFillPro:Ue,tierLabels:ze};function N({title:e,value:i,icon:a,subtitle:c,status:r,children:n}){const l=r?t[`metric_${r}`]:"";return s.jsxs("div",{className:`${t.metricCard} ${l}`,children:[s.jsxs("div",{className:t.metricHeader,children:[a&&s.jsx("span",{className:t.metricIcon,children:a}),s.jsx("span",{className:t.metricTitle,children:e})]}),s.jsx("div",{className:t.metricValue,children:i}),c&&s.jsx("div",{className:t.metricSubtitle,children:c}),n]})}function Oe(e){var a,c;const i=e==null?void 0:e.contextSummary;return(i==null?void 0:i.intent)??((c=(a=i==null?void 0:i.affectedAreas)==null?void 0:a[0])==null?void 0:c.label)??(i==null?void 0:i.testScenario)??null}function H({changes:e}){const{t:i}=R(),[a,c]=h.useState(null);return e.length===0?s.jsx("div",{className:t.feedEmpty,children:i("overview.feed.empty")}):s.jsx("div",{className:t.feedList,children:e.map((r,n)=>{const l=a===n,m=r.raw,u=m&&(m.before!=null||m.after!=null||m.details!=null),p=Oe(m);return s.jsxs("div",{children:[s.jsxs("div",{className:`${t.feedItem} ${u?t.feedItemClickable:""}`,onClick:()=>u&&c(l?null:n),children:[s.jsx("span",{className:t.feedTime,children:r.timestamp}),s.jsx("span",{className:t.feedIcon,children:r.icon}),s.jsxs("span",{className:t.feedText,children:[s.jsx("span",{className:t.feedSummary,children:r.summary}),p&&s.jsx("span",{className:t.feedContext,children:p})]}),u&&s.jsx("span",{className:t.feedChevron,children:l?"▴":"▾"})]}),l&&m&&s.jsx("div",{className:t.feedDetail,children:s.jsx(J,{change:m})})]},n)})})}const E=20;function G(e){return`${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`}function P(){return G(new Date)}function $(e){switch(e){case"script":return"📝";case"instance":return"🧱";case"property":return"🎨";case"lighting":return"💡";case"terrain":return"⛰️";case"asset":return"📦";default:return"🔧"}}function Xe(){const{level:e,status:i}=L(),a=F(),[c,r]=h.useState(null),[n,l]=h.useState(null),[m,u]=h.useState(null),[p,v]=h.useState([]),y=h.useRef(null),T=h.useCallback(async()=>{try{const o=await M.get("/connection-info");r(o)}catch{r(null)}},[]),S=h.useCallback(async()=>{try{const o=await M.get("/api/dashboard/changelog/active");if(u(o),o.recentChanges&&o.recentChanges.length>0){const w=o.recentChanges.map(g=>({timestamp:g.timestamp?G(new Date(g.timestamp)):P(),icon:$(g.category),summary:g.summary,category:g.category,raw:g}));v(w)}}catch{u(null)}},[]),f=h.useCallback(async()=>{try{const o=await M.get("/sync/status");l(o)}catch{l(null)}},[]);return h.useEffect(()=>{e!=="disconnected"?(T(),S(),f()):(r(null),l(null),u(null));const o=new V;y.current=o,o.connect();const w=o.on("game_change",x=>{const _=x,C={timestamp:P(),icon:$(_.category),summary:_.summary,category:_.category};v(k=>{const j=[C,...k];return j.length>E?j.slice(0,E):j}),S()}),g=o.on("sync",x=>{const _=x;l(C=>({...C,state:_.status,..._.placeId?{placeId:_.placeId}:{}}))});return()=>{w(),g(),o.disconnect(),y.current=null}},[e,T,S,f]),{level:e,status:i,connectionInfo:c,syncStatus:n,changeSummary:m,recentChanges:p,tier:a}}function D(e){return e.scriptsModified+e.scriptsCreated+e.instancesCreated+e.instancesDeleted+e.instancesMoved+e.propertiesChanged+e.assetsInserted+(e.lightingChanged?1:0)+(e.terrainChanged?1:0)}function qe(e,i){switch(e){case"syncing":return i("status.syncing","Syncing");case"initializing":return i("status.initializing","Initializing");case"error":return i("status.error","Error");default:return i("status.idle","Idle")}}function Je(e){switch(e){case"syncing":return"ok";case"initializing":return"warn";case"error":return"error";default:return"ok"}}function b(e,i,a,c){return s.jsxs("div",{className:e.metricSubtitle,children:[s.jsx(A,{label:i,tooltip:a}),": ",c]},i)}function d(e,i){return s.jsx(q,{text:i,children:e})}function ss(){var j,B;const{t:e}=R(),{level:i,status:a,connectionInfo:c,syncStatus:r,changeSummary:n,recentChanges:l}=Xe(),m=z(a==null?void 0:a.uptime),u=s.jsx(U,{title:e("page.overview.title","Overview"),description:e("page.overview.description","Check server, plugin, agent, sync, and recent game-change status in one place."),helpTopicId:"overview",helpState:{connectionLevel:i}});if(i==="disconnected")return s.jsxs("div",{className:t.page,children:[u,s.jsxs("div",{className:t.disconnectCard,children:[s.jsx("div",{className:t.disconnectIcon,children:"⚠️"}),s.jsx("h2",{className:t.disconnectTitle,children:e("overview.l0.title")}),s.jsx("p",{className:t.disconnectMessage,children:e("overview.l0.message")}),s.jsxs("div",{className:t.reconnectGuide,children:[s.jsxs("div",{className:t.guideStep,children:[s.jsx("span",{className:t.stepNumber,children:"1"}),s.jsx("span",{children:e("overview.l0.step1")})]}),s.jsxs("div",{className:t.guideStep,children:[s.jsx("span",{className:t.stepNumber,children:"2"}),s.jsx("span",{children:e("overview.l0.step2")})]})]}),s.jsxs("div",{className:t.reconnectIndicator,children:[s.jsx("span",{className:t.reconnectDot}),e("overview.l0.reconnecting")]}),s.jsxs("div",{className:t.disconnectActions,children:[s.jsx("button",{className:t.btn,onClick:()=>window.location.reload(),children:e("overview.l0.reconnectBtn")}),s.jsx("button",{className:t.btnSecondary,onClick:()=>{window.location.hash="#/settings"},children:e("overview.l0.settingsBtn")})]})]})]});const p=(c==null?void 0:c.mcpInstanceCount)??0,v=((j=c==null?void 0:c.mcpInstances)==null?void 0:j.find(I=>!I.isServer&&I.aiClientName))??((B=c==null?void 0:c.mcpInstances)==null?void 0:B.find(I=>!!I.aiClientName))??null,y=(a==null?void 0:a.pluginClients)??[],T=y.length>0,S=(a==null?void 0:a.sessionId)??(c==null?void 0:c.sessionId)??"-",f=e("overview.metric.server.tooltip","MCP server runtime and process status"),o=e("overview.metric.plugin.tooltip","Roblox Studio plugin connection and version status"),w=e("overview.metric.agent.tooltip","Connected AI coding agents and their runtime state"),g=e("overview.metric.sync.tooltip","Current Studio to local sync activity"),x=a?[b(t,e("overview.meta.version","Version"),e("overview.meta.version.tooltip","Installed MCP server version"),`v${a.version}`),b(t,e("overview.meta.session","Session"),e("overview.meta.session.tooltip","Current MCP session identifier"),S),b(t,e("overview.meta.pid","PID"),e("overview.meta.pid.tooltip","Operating system process identifier"),String(a.pid??"-")),b(t,e("overview.meta.uptime","Uptime"),e("overview.meta.uptime.tooltip","Time elapsed since the MCP server started"),O(m??a.uptime))]:[];if(i==="serverOnly")return s.jsxs("div",{className:t.page,children:[u,s.jsxs("div",{className:t.metricRow,children:[s.jsx(N,{title:d(e("overview.metric.server"),f),value:d(e("status.online"),f),icon:"🖥️",status:"ok",children:s.jsxs(s.Fragment,{children:[x,s.jsx(X,{status:"online"})]})}),s.jsx(N,{title:d(e("overview.metric.agent"),w),value:d((v==null?void 0:v.aiClientName)??e("overview.metric.noAgent"),w),icon:"🤖",subtitle:p>1?`${p} ${e("overview.metric.agent.instancesUnit","instances")}`:void 0,status:v?"ok":"warn"})]}),s.jsxs("div",{className:t.guideCard,children:[s.jsx("h3",{className:t.guideTitle,children:e("overview.l1.pluginGuide")}),s.jsxs("ul",{className:t.checklist,children:[s.jsx("li",{children:e("overview.l1.check1")}),s.jsx("li",{children:e("overview.l1.check2")})]})]}),s.jsxs("div",{className:t.card,children:[s.jsx("div",{className:t.cardHeader,children:e("overview.feed.title")}),l.length>0?s.jsx(H,{changes:l}):s.jsx("div",{className:t.feedEmpty,children:e("overview.l1.feedHint")})]}),n&&D(n)>0&&s.jsxs("div",{className:t.card,children:[s.jsx("div",{className:t.cardHeader,children:e("overview.changelog.title")}),s.jsxs("div",{className:t.changelogSummary,children:[s.jsxs("span",{children:[e("overview.changelog.entries","Entries"),": ",D(n)]}),n.scriptsModified>0&&s.jsxs("span",{className:t.changeTag,children:["📝"," ",n.scriptsModified," ",e("overview.changelog.scripts")]}),n.instancesCreated>0&&s.jsxs("span",{className:t.changeTag,children:["🧱"," ",n.instancesCreated," ",e("overview.changelog.instances")]}),n.propertiesChanged>0&&s.jsxs("span",{className:t.changeTag,children:["🎨"," ",n.propertiesChanged," ",e("overview.changelog.properties")]}),n.assetsInserted>0&&s.jsxs("span",{className:t.changeTag,children:["📦"," ",n.assetsInserted," ",e("overview.changelog.assets")]})]})]})]});const _=y[0],C=n?D(n):0,k=!!n&&C>0;return s.jsxs("div",{className:t.page,children:[u,s.jsxs("div",{className:t.metricGrid,children:[s.jsx(N,{title:d(e("overview.metric.server"),f),value:d(e("status.online"),f),icon:"🖥️",status:"ok",children:s.jsx(s.Fragment,{children:x})}),s.jsx(N,{title:d(e("overview.metric.plugin"),o),value:d(e(T?"status.online":"status.offline"),o),icon:"🔌",subtitle:_?`${_.placeName??"-"} / v${_.pluginVersion??"-"}`:void 0,status:T?"ok":"error"}),s.jsx(N,{title:d(e("overview.metric.agent"),w),value:d((v==null?void 0:v.aiClientName)??e("overview.metric.noAgent"),w),icon:"🤖",subtitle:p>1?`${p} ${e("overview.metric.agent.instancesUnit","instances")}`:void 0,status:v?"ok":"warn"}),s.jsx(N,{title:d(e("overview.metric.sync"),g),value:d(qe(r==null?void 0:r.state,e),g),icon:"🔄",status:Je(r==null?void 0:r.state)})]}),s.jsxs("div",{className:t.card,children:[s.jsx("div",{className:t.cardHeader,children:e("overview.feed.title")}),s.jsx(H,{changes:l})]}),k&&s.jsxs("div",{className:t.card,children:[s.jsx("div",{className:t.cardHeader,children:e("overview.changelog.title")}),s.jsxs("div",{className:t.changelogSummary,children:[s.jsxs("span",{children:[e("overview.changelog.entries","Entries"),": ",C]}),n.scriptsModified>0&&s.jsxs("span",{className:t.changeTag,children:["📝"," ",n.scriptsModified," ",e("overview.changelog.scripts")]}),n.instancesCreated>0&&s.jsxs("span",{className:t.changeTag,children:["🧱"," ",n.instancesCreated," ",e("overview.changelog.instances")]}),n.propertiesChanged>0&&s.jsxs("span",{className:t.changeTag,children:["🎨"," ",n.propertiesChanged," ",e("overview.changelog.properties")]}),n.assetsInserted>0&&s.jsxs("span",{className:t.changeTag,children:["📦"," ",n.assetsInserted," ",e("overview.changelog.assets")]})]})]})]})}export{ss as Component};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{f as oe,r as u,j as t,u as se,a as ae,X as re,E as ie,
|
|
1
|
+
import{f as oe,r as u,j as t,u as se,a as ae,X as re,E as ie,i as ce,x as le}from"./index-uP4eoQi-.js";/**
|
|
2
2
|
* @license lucide-react v1.8.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as t,C as i,G as m,q as v,H as x}from"./index-uP4eoQi-.js";const P="_details_1nw6u_1",I={details:P};function D(c,n,e,l,a,s,r,d){const f=c.isConnected?e:l,p=i(c),S=[f,p==="duplicate"?a:p==="unresolved"?s:null,d===!1?r:null].filter(u=>!!u);return`${n} (${c.placeId}) — ${S.join(" · ")}`}function $(c){const n=new Set;return c.filter(e=>e.placeId<=0||i(e)!=="unresolved"?!0:n.has(e.placeId)?!1:(n.add(e.placeId),!0))}function y(c,n){return Object.entries(n).reduce((e,[l,a])=>e.replace(`{${l}}`,a),c)}function L({places:c,confirmedNames:n,t:e}){const l=$(c),a=l.filter(o=>o.isConnected),s=l.filter(o=>!o.isConnected),r=e("placeScope.connected","Studio connected"),d=e("placeScope.stored","Stored data"),f=e("placeScope.folder.duplicate","Duplicate folder"),p=e("placeScope.folder.unresolved","Representative folder unconfirmed"),S=e("placeScope.folder.noSyncHistory","No sync history"),u=o=>{const h=m(o),b=v(c,o),j=x(c,o,n==null?void 0:n.get(o.placeId))??y(e("placeScope.folder.unresolvedPlace","Place {placeId}"),{placeId:String(o.placeId)});return t.jsx("option",{value:h?`folder:${o.placeDirName}`:o.placeId,disabled:h,children:D(o,j,r,d,f,p,S,b)},`${o.placeId}:${o.placeDirName}`)};return t.jsxs(t.Fragment,{children:[a.length>0?t.jsx("optgroup",{label:e("placeScope.connectedGroup","Connected Studios"),children:a.map(u)}):null,s.length>0?t.jsx("optgroup",{label:e("placeScope.storedGroup","Stored data"),children:s.map(u)}):null]})}function C({places:c,t:n}){const e=c.filter(l=>i(l)==="duplicate"||i(l)==="unresolved");return e.length===0?null:t.jsxs("details",{className:I.details,children:[t.jsx("summary",{children:n("placeScope.folder.details","Place folder details")}),t.jsx("ul",{children:e.map(l=>{const a=i(l)==="duplicate",s=a?n("placeScope.folder.duplicate","Duplicate folder"):n("placeScope.folder.unresolved","Representative folder unconfirmed"),r=a?y(n("placeScope.folder.duplicateReason","The current saved location is {canonicalFolder}. This folder is backed up after a successful full sync."),{canonicalFolder:l.canonicalPlaceDirName??n("placeScope.folder.unknown","unknown")}):n("placeScope.folder.unresolvedReason","This Place remains selectable by ID, but no specific folder is confirmed as the representative yet."),d=l.hasSyncMetadata===!1?`${n("placeScope.folder.noSyncHistory","No sync history")}. ${r}`:r;return t.jsxs("li",{children:[t.jsx("strong",{children:s}),t.jsx("span",{children:l.placeDirName}),t.jsx("span",{children:d})]},`${l.placeId}:${l.placeDirName}`)})})]})}export{L as P,C as a};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as i,r as c,j as r}from"./index-
|
|
1
|
+
import{u as i,r as c,j as r}from"./index-uP4eoQi-.js";import{A as n}from"./AiPromptExamples-BSFrFYar.js";const m=["character","automated-check","selection","game-state","action"];function y(t){return m.map(a=>({id:a,title:t(`playtest.ai.examples.${a}.title`),request:t(`playtest.ai.examples.${a}.request`)}))}function d(t){const{locale:a,t:e}=i(),s=t.exampleIds.join("|"),o=c.useMemo(()=>{const p=new Set(t.exampleIds);return y(e).filter(l=>p.has(l.id))},[s,e]);return r.jsx(n,{examples:o,resetKey:`${a}|${s}`,labels:{copy:e("playtest.ai.copy","Copy request"),copying:e("playtest.ai.copying","Copying…"),copied:e("playtest.ai.copied","Copied"),copyFailed:e("playtest.ai.copyFailed","Could not copy. Select the request text and copy it manually.")}})}export{d as P};
|