@weppy/roblox-mcp 2.16.0 → 2.16.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dashboard/dist/assets/{AssetsPage-Dcj0TWe9.js → AssetsPage-_CPMetwm.js} +2 -2
  3. package/dashboard/dist/assets/ChangelogPage-B9Ct115r.css +1 -0
  4. package/dashboard/dist/assets/ChangelogPage-BpTjHwvr.js +1 -0
  5. package/dashboard/dist/assets/{ConfirmModal-CyjUVYwz.js → ConfirmModal-BSbhJt6x.js} +1 -1
  6. package/dashboard/dist/assets/{ConnectionPage-B1tZK4zW.js → ConnectionPage-BMIbBueG.js} +2 -2
  7. package/dashboard/dist/assets/ContentScopedDialog-D92wgDaU.js +1 -0
  8. package/dashboard/dist/assets/ContentScopedDialog-DCgVfmeB.css +1 -0
  9. package/dashboard/dist/assets/{ControlsPage-zlLRwkt6.js → ControlsPage-C828Cgwo.js} +2 -2
  10. package/dashboard/dist/assets/CurrentPlaceScope-BFYSAg2T.js +1 -0
  11. package/dashboard/dist/assets/{GameChangeDetail-CONsGQ2-.js → GameChangeDetail-CCQ8h1ft.js} +1 -1
  12. package/dashboard/dist/assets/{InfoLabel-Cf_fu0ZE.js → InfoLabel-D6WxKFnG.js} +1 -1
  13. package/dashboard/dist/assets/OverviewPage-B8RMrIaQ.js +1 -0
  14. package/dashboard/dist/assets/{UiPrimitive-BMSNRGwI.css → PageHeader-CrhjZjgp.css} +1 -1
  15. package/dashboard/dist/assets/PageHeader-Xrn6BpcL.js +6 -0
  16. package/dashboard/dist/assets/PlaytestPage-C-WO2SsY.css +1 -0
  17. package/dashboard/dist/assets/PlaytestPage-CrCurhRT.js +11 -0
  18. package/dashboard/dist/assets/SettingsPage-B_9NwPEF.js +1 -0
  19. package/dashboard/dist/assets/{StatusBadge-DPEvJdzm.js → StatusBadge-Ddzg1cSk.js} +1 -1
  20. package/dashboard/dist/assets/SyncPage-BNadN0NU.js +1 -0
  21. package/dashboard/dist/assets/{Tabs-BXHuo9Wk.js → Tabs-DZDOsT6_.js} +1 -1
  22. package/dashboard/dist/assets/ToolsPage-B4t6LvfV.css +1 -0
  23. package/dashboard/dist/assets/ToolsPage-bHm2QbDR.js +1 -0
  24. package/dashboard/dist/assets/{TooltipText-55u9HaGy.js → TooltipText-B1An7dUI.js} +1 -1
  25. package/dashboard/dist/assets/UiStudioPage-CWQgLMHO.js +11 -0
  26. package/dashboard/dist/assets/{UiStudioPage-Cej06eXQ.css → UiStudioPage-Ds-eaGvd.css} +1 -1
  27. package/dashboard/dist/assets/WhatsNewPage-D-iibgAc.js +1 -0
  28. package/dashboard/dist/assets/{copy-szgBQciT.js → copy-B03ftJiE.js} +1 -1
  29. package/dashboard/dist/assets/{index-CACN5u4J.js → index-Ygt1Wh6v.js} +26 -26
  30. package/dashboard/dist/assets/sample-requests-r6iFLFba.js +1 -0
  31. package/dashboard/dist/assets/{useLiveUptime-kOkM_pqk.js → useLiveUptime-CnfGQ_vS.js} +1 -1
  32. package/dashboard/dist/assets/useSettings-BrnGUYZY.js +1 -0
  33. package/dashboard/dist/index.html +1 -1
  34. package/dist/index.js +91 -91
  35. package/package.json +1 -1
  36. package/roblox-plugin/WeppyRobloxMCP.rbxm +0 -0
  37. package/dashboard/dist/assets/ChangelogDetailPage-Bw3gyr1A.js +0 -1
  38. package/dashboard/dist/assets/ChangelogDetailPage-vGgnpq1q.css +0 -1
  39. package/dashboard/dist/assets/ChangelogPage-0WZSh2m-.js +0 -1
  40. package/dashboard/dist/assets/ChangelogPage-DsP0fTsc.css +0 -1
  41. package/dashboard/dist/assets/CurrentPlaceScope-BdkdaT7r.js +0 -1
  42. package/dashboard/dist/assets/OverviewPage-B7Y5VEFH.js +0 -1
  43. package/dashboard/dist/assets/PageHeader-CTOJDcG8.js +0 -6
  44. package/dashboard/dist/assets/PageHeader-CV_rjuG8.css +0 -1
  45. package/dashboard/dist/assets/PlaytestPage-BJq2ns66.css +0 -1
  46. package/dashboard/dist/assets/PlaytestPage-Zab8aOB7.js +0 -11
  47. package/dashboard/dist/assets/SettingsPage-CizCAf2d.js +0 -1
  48. package/dashboard/dist/assets/SyncPage-M1CTHa74.js +0 -1
  49. package/dashboard/dist/assets/ToolsPage-CAaH9fIQ.css +0 -1
  50. package/dashboard/dist/assets/ToolsPage-oPc2T58z.js +0 -1
  51. package/dashboard/dist/assets/UiPrimitive-BUpeGXNh.js +0 -1
  52. package/dashboard/dist/assets/UiStudioPage-Ck1kJetD.js +0 -11
  53. package/dashboard/dist/assets/WhatsNewPage-BoTRERVd.js +0 -1
  54. package/dashboard/dist/assets/sample-requests-DOSLzn1v.js +0 -1
  55. package/dashboard/dist/assets/useSettings-COna4-LR.js +0 -1
@@ -0,0 +1 @@
1
+ import{r as o,b as G,D as Q,u as U,j as e,X as W,a as X,p as Y,c as J,e as ee,i as te,T as ne}from"./index-Ygt1Wh6v.js";import{B as ae,P as se}from"./PageHeader-Xrn6BpcL.js";import{C as ie}from"./ConfirmModal-BSbhJt6x.js";import{C as ce}from"./CurrentPlaceScope-BFYSAg2T.js";import{T as D}from"./TooltipText-B1An7dUI.js";import{C as oe}from"./ContentScopedDialog-D92wgDaU.js";import{I as re}from"./InfoLabel-D6WxKFnG.js";import{G as le}from"./GameChangeDetail-CCQ8h1ft.js";import{T as de}from"./Tabs-DZDOsT6_.js";import"./ConfirmModal.module-DJksQHBd.js";const me=10;function ge(t,i){return typeof i!="number"?t:`${t}?placeId=${encodeURIComponent(String(i))}`}function he(t){const i=(t==null?void 0:t.placeId)??null,[g,c]=o.useState([]),[a,s]=o.useState(0),[u,p]=o.useState(!1),[r,T]=o.useState(!0),[b,L]=o.useState(0),[y,E]=o.useState("all"),B=o.useRef(null),C=o.useCallback(async(f,S)=>{T(!0);try{const k={limit:String(me),offset:String(f)};S!=="all"&&(k.status=S),typeof i=="number"&&(k.placeId=String(i));const w=await G.get("/api/dashboard/changelog",k);c(w.entries),s(w.total),p(w.hasMore)}catch{c([]),s(0),p(!1)}finally{T(!1)}},[i]),I=o.useCallback(()=>{C(b,y)},[C,b,y]),$=o.useCallback(async()=>{await G.post(ge("/api/dashboard/changelog/clear",i)),c([]),s(0),p(!1)},[i]);return o.useEffect(()=>{C(b,y)},[C,b,y]),o.useEffect(()=>{const f=new Q;B.current=f,f.connect();const S=f.on("command",()=>{C(b,y)});return()=>{S(),f.disconnect(),B.current=null}},[C,b,y]),{entries:g,total:a,hasMore:u,loading:r,offset:b,statusFilter:y,setOffset:L,setStatusFilter:E,refresh:I,clear:$}}const ue="_card_qniob_2",pe="_header_qniob_27",ye="_statusBadge_qniob_34",fe="_statusDot_qniob_45",xe="_active_qniob_51",_e="_completed_qniob_60",je="_timeRange_qniob_68",be="_summaryList_qniob_75",Ce="_summaryItem_qniob_81",Se="_summaryIcon_qniob_90",ve="_summaryText_qniob_96",Ne="_progressBar_qniob_101",Te="_progressFill_qniob_110",Ie="_emptySummary_qniob_124",ke="_contextBlock_qniob_132",we="_contextLabel_qniob_141",$e="_contextValue_qniob_149",h={card:ue,header:pe,statusBadge:ye,statusDot:fe,active:xe,completed:_e,timeRange:je,summaryList:be,summaryItem:Ce,summaryIcon:Se,summaryText:ve,progressBar:Ne,progressFill:Te,emptySummary:Ie,contextBlock:ke,contextLabel:we,contextValue:$e};function Z(t){if(!t)return"--:--";const i=new Date(t);return`${String(i.getHours()).padStart(2,"0")}:${String(i.getMinutes()).padStart(2,"0")}`}function Be({entry:t,onClick:i,buttonRef:g}){var S,k,w,A,R,M,d,_,F,O;const{t:c}=U(),a=t.changeSummary,s=t.status==="active",u=t.isBootstrapOnly===!0,p=[],r=a.scriptsModified+a.scriptsCreated;if(r>0){const m=[];a.scriptsModified>0&&m.push(`${a.scriptsModified} ${c("changelog.card.modified","modified")}`),a.scriptsCreated>0&&m.push(`${a.scriptsCreated} ${c("changelog.card.created","created")}`);const x=`${r} ${c("changelog.card.scripts","scripts")} ${m.join(", ")}`;p.push({icon:"📝",text:x,tooltip:c("changelog.card.scripts.tooltip","Script changes made in this session.")})}const T=a.instancesCreated+a.instancesDeleted+a.instancesMoved;if(T>0){const m=[];a.instancesCreated>0&&m.push(`${a.instancesCreated} ${c("changelog.card.created","created")}`),a.instancesDeleted>0&&m.push(`${a.instancesDeleted} ${c("changelog.card.deleted","deleted")}`),a.instancesMoved>0&&m.push(`${a.instancesMoved} ${c("changelog.card.moved","moved")}`);const x=`${T} ${c("changelog.card.instances","instances")} ${m.join(", ")}`;p.push({icon:"🧱",text:x,tooltip:c("changelog.card.instances.tooltip","Instance create, delete, move, or clone changes in this session.")})}a.propertiesChanged>0&&p.push({icon:"🎨",text:`${a.propertiesChanged} ${c("changelog.card.propertiesChanged","properties changed")}`,tooltip:c("changelog.card.propertiesChanged.tooltip","Property value changes recorded for this session.")}),a.lightingChanged&&p.push({icon:"🌅",text:c("changelog.card.lightingConfigured","Lighting configured"),tooltip:c("changelog.card.lightingConfigured.tooltip","Lighting or atmosphere settings changed in this session.")}),a.terrainChanged&&p.push({icon:"⛰️",text:c("changelog.card.terrainConfigured","Terrain configured"),tooltip:c("changelog.card.terrainConfigured.tooltip","Terrain data or terrain settings changed in this session.")}),a.assetsInserted>0&&p.push({icon:"📦",text:`${a.assetsInserted} ${c("changelog.card.assetsInserted","assets inserted")}`,tooltip:c("changelog.card.assetsInserted.tooltip","Assets inserted into the place during this session.")});const b=Z(t.startTime),L=s?c("changelog.card.inProgress","in progress"):t.endTime?Z(t.endTime):"--:--",y=u?c("changelog.card.bootstrapStatus","Bootstrap"):s?c("changelog.card.active","Active"):c("changelog.card.completed","Completed"),E=u?c("changelog.card.bootstrapStatus.tooltip","This session only contains the initial sync bootstrap snapshot."):s?c("changelog.card.active.tooltip","This session is still receiving new game changes."):c("changelog.card.completed.tooltip","This session has ended and no more changes are expected."),B=u?c("changelog.card.bootstrapSummary","Initial sync snapshot"):c("changelog.card.noChanges","No changes yet"),C=u?c("changelog.card.bootstrapSummary.tooltip","Initial file sync writes are collapsed into a single bootstrap snapshot row."):c("changelog.card.noChanges.tooltip","No game changes have been extracted for this session yet."),I=(k=(S=t.contextSummary)==null?void 0:S.intent)==null?void 0:k.trim(),$=((M=(R=(A=(w=t.contextSummary)==null?void 0:w.affectedAreas)==null?void 0:A[0])==null?void 0:R.label)==null?void 0:M.trim())||((_=(d=t.contextSummary)==null?void 0:d.testScenario)==null?void 0:_.trim()),f=(O=(F=t.verificationSummary)==null?void 0:F.label)==null?void 0:O.trim();return e.jsxs("button",{ref:g,className:h.card,type:"button",onClick:m=>i(m.currentTarget),children:[e.jsxs("span",{className:h.header,children:[e.jsx(D,{text:E,children:e.jsxs("span",{className:`${h.statusBadge} ${s?h.active:h.completed}`,children:[e.jsx("span",{className:h.statusDot}),y]})}),e.jsxs("span",{className:h.timeRange,children:[b,"~",L]})]}),e.jsx("span",{className:h.summaryList,children:p.length>0?p.map((m,x)=>e.jsxs("span",{className:h.summaryItem,children:[e.jsx("span",{className:h.summaryIcon,children:m.icon}),e.jsx(D,{text:m.tooltip,children:e.jsx("span",{className:h.summaryText,children:m.text})})]},x)):e.jsx(D,{text:C,children:e.jsx("span",{className:h.emptySummary,style:{display:"block"},children:B})})}),I&&e.jsxs("span",{className:h.contextBlock,children:[e.jsx("span",{className:h.contextLabel,children:c("changelog.card.sessionIntent","Session intent")}),e.jsx("span",{className:h.contextValue,children:I})]}),!I&&$&&e.jsxs("span",{className:h.contextBlock,children:[e.jsx("span",{className:h.contextLabel,children:c("changelog.card.representativeArea","Representative area")}),e.jsx("span",{className:h.contextValue,children:$})]}),f&&e.jsxs("span",{className:h.contextBlock,children:[e.jsx("span",{className:h.contextLabel,children:c("changelog.card.verification","Verification")}),e.jsx("span",{className:h.contextValue,children:f})]}),s&&e.jsx("span",{className:h.progressBar,children:e.jsx("span",{className:h.progressFill})})]})}function Ee(t){const i={scriptsModified:0,scriptsCreated:0,instancesCreated:0,instancesDeleted:0,instancesMoved:0,propertiesChanged:0,lightingChanged:!1,terrainChanged:!1,assetsInserted:0};for(const g of t)switch(g.category){case"script":g.changeType==="create"?i.scriptsCreated++:i.scriptsModified++;break;case"instance":g.changeType==="create"?i.instancesCreated++:g.changeType==="delete"?i.instancesDeleted++:g.changeType==="move"&&i.instancesMoved++;break;case"property":i.propertiesChanged++;break;case"lighting":i.lightingChanged=!0;break;case"terrain":i.terrainChanged=!0;break;case"asset":i.assetsInserted++;break}return i}function Le(t){if(typeof t=="number")return{placeId:String(t)}}function Ae(t,i){const[g,c]=o.useState(""),[a,s]=o.useState(""),[u,p]=o.useState(),[r,T]=o.useState("completed"),[b,L]=o.useState([]),[y,E]=o.useState([]),[B,C]=o.useState([]),[I,$]=o.useState(),[f,S]=o.useState(),[k,w]=o.useState(),[A,R]=o.useState({scriptsModified:0,scriptsCreated:0,instancesCreated:0,instancesDeleted:0,instancesMoved:0,propertiesChanged:0,lightingChanged:!1,terrainChanged:!1,assetsInserted:0}),[M,d]=o.useState(!0),[_,F]=o.useState(null),O=o.useCallback(async()=>{if(t){d(!0),F(null);try{const m=Le(i),[x,K]=await Promise.all([m?G.get(`/api/dashboard/changelog/${t}`,m):G.get(`/api/dashboard/changelog/${t}`),m?G.get(`/api/dashboard/changelog/${t}/changes`,m):G.get(`/api/dashboard/changelog/${t}/changes`)]);c(x.entryId),s(x.startTime),p(x.endTime),T(x.status),L(x.entries),E(x.failures),$(x.contextSummary),S(x.replayMetadata),w(x.verificationSummary),C(K.changes),R(Ee(K.changes))}catch(m){F(m instanceof Error?m.message:"Failed to load changelog detail")}finally{d(!1)}}},[t,i]);return o.useEffect(()=>{O()},[O]),{entryId:g,startTime:a,endTime:u,status:r,entries:b,failures:y,changes:B,changeSummary:A,contextSummary:I,replayMetadata:f,verificationSummary:k,loading:M,error:_,refresh:O}}const Re={script:"📝",instance:"🧱",property:"🎨",lighting:"🌅",terrain:"⛰️",asset:"📦"};function Me(t){return Re[t]??"❓"}const Oe="_dialogContent_djmny_2",De="_dialogHeader_djmny_10",Fe="_dialogTitleGroup_djmny_20",Pe="_dialogTitle_djmny_20",Ge="_dialogMeta_djmny_35",Ke="_dialogClose_djmny_42",Ve="_dialogBody_djmny_67",qe="_page_djmny_76",Ue="_headerTime_djmny_83",He="_dialogActions_djmny_89",Ze="_retryButton_djmny_95",ze="_statusActive_djmny_128",Qe="_statusCompleted_djmny_133",We="_section_djmny_138",Xe="_sectionTitle_djmny_145",Ye="_summaryGrid_djmny_158",Je="_summaryCard_djmny_164",et="_summaryCardActive_djmny_187",tt="_summaryIcon_djmny_192",nt="_summaryCount_djmny_198",at="_summaryLabel_djmny_206",st="_contextGrid_djmny_216",it="_contextRow_djmny_222",ct="_contextKey_djmny_228",ot="_contextValue_djmny_236",rt="_timelineFilter_djmny_244",lt="_filterLabel_djmny_252",dt="_filterSelect_djmny_258",mt="_ownershipToggle_djmny_268",gt="_timeline_djmny_244",ht="_timelineEntry_djmny_296",ut="_timelineTime_djmny_325",pt="_timelineIcon_djmny_333",yt="_timelineBody_djmny_338",ft="_timelineSummary_djmny_344",xt="_timelineTarget_djmny_352",_t="_timelineConfidence_djmny_360",jt="_ownershipBadge_djmny_369",bt="_confidenceExact_djmny_377",Ct="_confidencePartial_djmny_382",St="_confidenceAfterOnly_djmny_387",vt="_confidenceIntentOnly_djmny_392",Nt="_confidenceUnknown_djmny_397",Tt="_timelineExpanded_djmny_403",It="_empty_djmny_412",kt="_loading_djmny_421",wt="_error_djmny_430",n={dialogContent:Oe,dialogHeader:De,dialogTitleGroup:Fe,dialogTitle:Pe,dialogMeta:Ge,dialogClose:Ke,dialogBody:Ve,page:qe,headerTime:Ue,dialogActions:He,retryButton:Ze,statusActive:ze,statusCompleted:Qe,section:We,sectionTitle:Xe,summaryGrid:Ye,summaryCard:Je,summaryCardActive:et,summaryIcon:tt,summaryCount:nt,summaryLabel:at,contextGrid:st,contextRow:it,contextKey:ct,contextValue:ot,timelineFilter:rt,filterLabel:lt,filterSelect:dt,ownershipToggle:mt,timeline:gt,timelineEntry:ht,timelineTime:ut,timelineIcon:pt,timelineBody:yt,timelineSummary:ft,timelineTarget:xt,timelineConfidence:_t,ownershipBadge:jt,confidenceExact:bt,confidencePartial:Ct,confidenceAfterOnly:St,confidenceIntentOnly:vt,confidenceUnknown:Nt,timelineExpanded:Tt,empty:It,loading:kt,error:wt},z=[{key:"script",icon:"📝",labelKey:"changelog.category.script"},{key:"instance",icon:"🧱",labelKey:"changelog.category.instance"},{key:"property",icon:"🎨",labelKey:"changelog.category.property"},{key:"lighting",icon:"🌅",labelKey:"changelog.category.lighting"},{key:"terrain",icon:"⛰️",labelKey:"changelog.category.terrain"},{key:"asset",icon:"📦",labelKey:"changelog.category.asset"}];function q(t){if(!t)return"--:--";const i=new Date(t);return`${String(i.getHours()).padStart(2,"0")}:${String(i.getMinutes()).padStart(2,"0")}`}function $t(t){if(!t)return"--:--:--";const i=new Date(t);return`${String(i.getHours()).padStart(2,"0")}:${String(i.getMinutes()).padStart(2,"0")}:${String(i.getSeconds()).padStart(2,"0")}`}function Bt(t,i){if(!t||!i)return"";const g=new Date(i).getTime()-new Date(t).getTime();return g<0?"":`${Math.round(g/6e4)}min`}function Et(t){switch(t){case"exact":return n.confidenceExact;case"partial":return n.confidencePartial;case"after-only":return n.confidenceAfterOnly;case"intent-only":return n.confidenceIntentOnly;default:return n.confidenceUnknown}}function Lt(t,i){switch(i){case"exact":return t("changelog.detail.confidence.exact","Exact");case"partial":return t("changelog.detail.confidence.partial","Partial");case"after-only":return t("changelog.detail.confidence.afterOnly","After only");case"intent-only":return t("changelog.detail.confidence.intentOnly","Intent only");default:return t("changelog.detail.confidence.unknown","Unknown")}}function At(t,i){switch(i){case"exact":return t("changelog.detail.confidence.exact.tooltip","Both the before and after state were confirmed for this change.");case"partial":return t("changelog.detail.confidence.partial.tooltip","Only part of the before and after state could be confirmed for this change.");case"after-only":return t("changelog.detail.confidence.afterOnly.tooltip","Only the resulting state after the change could be confirmed.");case"intent-only":return t("changelog.detail.confidence.intentOnly.tooltip","Only the requested action was recorded, not the resulting state.");default:return t("changelog.detail.confidence.unknown.tooltip","This change could not be confidently classified from the available data.")}}function Rt(t,i){switch(i){case"user_source":return t("changelog.ownership.userSource","User source");case"canonical_mirror":return t("changelog.ownership.canonicalMirror","Mirror metadata");case"generated":return t("changelog.ownership.generated","Generated");default:return null}}function Mt({entryId:t,placeId:i,onClose:g,returnFocusTo:c=null}){var S,k,w,A,R,M,d,_,F,O,m,x,K,H;const{t:a}=U(),s=Ae(t,i),[u,p]=o.useState("all"),[r,T]=o.useState(!0),[b,L]=o.useState(null),y=o.useMemo(()=>{const l=r?s.changes:s.changes.filter(j=>j.artifactOwnership!=="generated");return[...u==="all"?l:l.filter(j=>j.category===u)].reverse()},[s.changes,u,r]),E=s.changes.some(l=>l.artifactOwnership==="generated"),B=Bt(s.startTime,s.endTime),C=s.endTime?`${q(s.startTime)} → ${q(s.endTime)} (${B})`:`${q(s.startTime)} → ${a("changelog.card.inProgress","in progress")}`,I=!!((S=s.contextSummary)!=null&&S.intent||(k=s.contextSummary)!=null&&k.testScenario||(w=s.contextSummary)!=null&&w.expectedBehavior||(A=s.contextSummary)!=null&&A.observedBehavior),$=!!((R=s.verificationSummary)!=null&&R.label||(M=s.verificationSummary)!=null&&M.status||(d=s.verificationSummary)!=null&&d.testTimestamp),f=a("changelog.detail.dialogLabel","Changelog detail");return e.jsx(oe,{open:!0,ariaLabel:f,onClose:g,returnFocusTo:c,testId:"changelog-detail-backdrop",children:e.jsxs("div",{className:n.dialogContent,children:[e.jsxs("div",{className:n.dialogHeader,children:[e.jsxs("div",{className:n.dialogTitleGroup,children:[e.jsx("h2",{className:n.dialogTitle,children:f}),!s.loading&&!s.error&&e.jsxs("div",{className:n.dialogMeta,children:[e.jsx("span",{className:n.headerTime,children:C}),e.jsx(D,{text:s.status==="active"?a("changelog.card.active.tooltip","This session is still receiving new game changes."):a("changelog.card.completed.tooltip","This session has ended and no more changes are expected."),children:e.jsx("span",{className:s.status==="active"?n.statusActive:n.statusCompleted,children:s.status==="active"?a("changelog.card.active","Active"):a("changelog.card.completed","Completed")})})]})]}),e.jsx("button",{className:n.dialogClose,type:"button","aria-label":a("common.close","Close"),onClick:g,children:e.jsx(W,{size:18,"aria-hidden":"true"})})]}),e.jsxs("div",{className:n.dialogBody,children:[s.loading&&e.jsx("div",{className:n.loading,children:a("common.loading","Loading...")}),s.error&&e.jsxs("div",{className:n.error,children:[e.jsx("span",{children:s.error}),e.jsxs("div",{className:n.dialogActions,children:[e.jsx("button",{className:n.retryButton,type:"button",onClick:s.refresh,children:a("common.retry","Retry")}),e.jsx("button",{className:n.retryButton,type:"button",onClick:g,children:a("common.close","Close")})]})]}),!s.loading&&!s.error&&e.jsxs("div",{className:n.page,children:[e.jsxs("div",{className:n.section,children:[e.jsx("div",{className:n.sectionTitle,children:e.jsx(D,{text:a("changelog.detail.changeSummary.tooltip","Counts of extracted game changes grouped by category for this session."),children:e.jsx("span",{children:a("changelog.detail.changeSummary","Change Summary")})})}),e.jsx("div",{className:n.summaryGrid,children:z.map(l=>{const v=s.changeSummary;let j;switch(l.key){case"script":j=v.scriptsModified+v.scriptsCreated;break;case"instance":j=v.instancesCreated+v.instancesDeleted+v.instancesMoved;break;case"property":j=v.propertiesChanged;break;case"lighting":j=v.lightingChanged?1:0;break;case"terrain":j=v.terrainChanged?1:0;break;case"asset":j=v.assetsInserted;break;default:j=0}const P=u===l.key;return e.jsxs("button",{type:"button",className:`${n.summaryCard} ${P?n.summaryCardActive:""}`,"aria-label":`${a(l.labelKey,l.key)}: ${j}`,"aria-pressed":P,onClick:()=>p(P?"all":l.key),children:[e.jsx("span",{className:n.summaryIcon,children:l.icon}),e.jsx("span",{className:n.summaryCount,children:j}),e.jsx("span",{className:n.summaryLabel,children:a(l.labelKey,l.key)})]},l.key)})})]}),I&&e.jsxs("div",{className:n.section,children:[e.jsx("div",{className:n.sectionTitle,children:e.jsx(D,{text:a("changelog.detail.context.tooltip","Structured execution context captured for this changelog session."),children:e.jsx("span",{children:a("changelog.detail.context.title","Context Summary")})})}),e.jsxs("div",{className:n.contextGrid,children:[((_=s.contextSummary)==null?void 0:_.intent)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:a("changelog.card.sessionIntent","Session intent")}),e.jsx("span",{className:n.contextValue,children:s.contextSummary.intent})]}),((F=s.contextSummary)==null?void 0:F.testScenario)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:a("playtest.context.why","Why this test ran")}),e.jsx("span",{className:n.contextValue,children:s.contextSummary.testScenario})]}),((O=s.contextSummary)==null?void 0:O.expectedBehavior)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:a("playtest.context.expected","Expected")}),e.jsx("span",{className:n.contextValue,children:s.contextSummary.expectedBehavior})]}),((m=s.contextSummary)==null?void 0:m.observedBehavior)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:a("playtest.context.observed","Observed")}),e.jsx("span",{className:n.contextValue,children:s.contextSummary.observedBehavior})]})]})]}),$&&e.jsxs("div",{className:n.section,children:[e.jsx("div",{className:n.sectionTitle,children:e.jsx(D,{text:a("changelog.detail.verification.tooltip","Verification signals linked to this changelog session."),children:e.jsx("span",{children:a("changelog.detail.verification.title","Verification")})})}),e.jsxs("div",{className:n.contextGrid,children:[((x=s.verificationSummary)==null?void 0:x.label)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:a("changelog.detail.verification.label","Result")}),e.jsx("span",{className:n.contextValue,children:s.verificationSummary.label})]}),((K=s.verificationSummary)==null?void 0:K.status)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:a("changelog.detail.verification.status","Status")}),e.jsx("span",{className:n.contextValue,children:s.verificationSummary.status})]}),((H=s.verificationSummary)==null?void 0:H.testTimestamp)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:a("changelog.detail.verification.timestamp","Recorded at")}),e.jsx("span",{className:n.contextValue,children:s.verificationSummary.testTimestamp})]})]})]}),e.jsxs("div",{className:n.section,children:[e.jsx("div",{className:n.sectionTitle,children:e.jsx(D,{text:a("changelog.detail.changeTimeline.tooltip","Chronological list of extracted game changes for this session."),children:e.jsx("span",{children:a("changelog.detail.changeTimeline","Change Timeline")})})}),e.jsxs("div",{className:n.timelineFilter,children:[e.jsx("span",{className:n.filterLabel,children:e.jsx(re,{label:`${a("changelog.detail.filterCategory","Category")}:`,tooltip:a("changelog.detail.filterCategory.tooltip","Filter the timeline to a single change category.")})}),e.jsxs("select",{className:n.filterSelect,value:u,onChange:l=>p(l.target.value),children:[e.jsx("option",{value:"all",children:a("tools.filter.all","All")}),z.map(l=>e.jsxs("option",{value:l.key,children:[l.icon," ",a(l.labelKey,l.key)]},l.key))]}),E&&e.jsxs("label",{className:n.ownershipToggle,children:[e.jsx("input",{type:"checkbox",checked:r,onChange:l=>T(l.target.checked)}),a("changelog.ownership.showGenerated","Show generated metadata")]})]}),y.length===0?e.jsx("div",{className:n.empty,children:a("changelog.detail.noChanges","No changes in this category")}):e.jsx("div",{className:n.timeline,children:y.map((l,v)=>{const j=b===v,P=Rt(a,l.artifactOwnership);return e.jsxs("div",{children:[e.jsxs("button",{type:"button",className:n.timelineEntry,"aria-expanded":j,onClick:()=>L(j?null:v),children:[e.jsx("span",{className:n.timelineTime,children:$t(l.timestamp)}),e.jsx("span",{className:n.timelineIcon,children:Me(l.category)}),e.jsxs("span",{className:n.timelineBody,children:[e.jsxs("span",{className:n.timelineSummary,children:[l.summary,P&&e.jsx(ae,{variant:l.artifactOwnership==="generated"?"neutral":"accent",className:n.ownershipBadge,children:P}),e.jsx(D,{text:At(a,l.confidence),children:e.jsx("span",{className:`${n.timelineConfidence} ${Et(l.confidence)}`,children:Lt(a,l.confidence)})})]}),e.jsx("span",{className:n.timelineTarget,children:l.target})]})]}),j&&e.jsx("div",{className:n.timelineExpanded,children:e.jsx(le,{change:l})})]},v)})})]})]})]})]})})}const Ot="_page_1tggr_2",Dt="_limitNotice_1tggr_9",Ft="_limitNoticeContent_1tggr_23",Pt="_limitNoticeTitle_1tggr_28",Gt="_limitNoticeText_1tggr_35",Kt="_primaryAction_1tggr_41",Vt="_clearButton_1tggr_67",qt="_list_1tggr_88",Ut="_empty_1tggr_95",Ht="_loading_1tggr_104",Zt="_pagination_1tggr_113",zt="_pageInfo_1tggr_121",Qt="_btn_1tggr_127",N={page:Ot,limitNotice:Dt,limitNoticeContent:Ft,limitNoticeTitle:Pt,limitNoticeText:Gt,primaryAction:Kt,clearButton:Vt,list:qt,empty:Ut,loading:Ht,pagination:Zt,pageInfo:zt,btn:Qt},V=10;function Wt(t,i){return typeof i!="number"?`/changelog/${t}`:`/changelog/${t}?placeId=${encodeURIComponent(String(i))}`}function Xt(t){const i=/^\/changelog\/([^/]+)$/.exec(t);if(!i)return null;try{return decodeURIComponent(i[1])}catch{return i[1]}}function Yt(t){const i=new URLSearchParams(t).get("placeId");if(!i)return null;const g=Number.parseInt(i,10);return Number.isInteger(g)&&g>=0?g:null}const Jt=[{key:"all",labelKey:"changelog.filter.all"},{key:"active",labelKey:"changelog.filter.active"},{key:"completed",labelKey:"changelog.filter.completed"}];function mn(){const{t}=U(),{trackEvent:i,trackPageView:g}=X(),c=Y(),a=J(),s=Xt(a.pathname),[u,p]=o.useState(()=>Yt(a.search)),r=he({placeId:u}),T=ee(),{show:b}=te(),[L,y]=o.useState(!1),[E,B]=o.useState(!1),[C,I]=o.useState(null),$=o.useRef(null),f=s??C,S=!T.loading&&T.tier==="basic",k=S?r.entries.slice(0,3):r.entries,w=!S&&r.total>V;o.useEffect(()=>{s&&s===C&&I(null)},[C,s]);const A=async()=>{B(!0);try{await r.clear(),b(t("toast.clearSuccess","Cleared successfully"),"success"),y(!1)}catch{b(t("toast.clearFailed","Failed to clear data"),"error")}finally{B(!1)}},R=(d,_)=>{$.current=_,I(d),c(Wt(d,u))},M=()=>{I(null),c("/changelog",{replace:!0})};return e.jsxs("div",{className:N.page,children:[e.jsx(se,{title:t("page.changelog.title","Changelog"),description:t("page.changelog.description","Review game-change sessions captured from AI actions and sync events."),helpTopicId:"changelog",helpState:{tier:T.tier}}),e.jsx(ce,{surface:"changelog",selectable:!0,selectedPlaceId:u,onSelectedPlaceIdChange:d=>{p(d),r.setOffset(0)}}),e.jsx(de,{items:Jt.map(d=>({key:d.key,label:t(d.labelKey,d.key.charAt(0).toUpperCase()+d.key.slice(1))})),value:r.statusFilter,onChange:d=>{const _=`changelog_${d}`;i("dashboard_click_event",{click_target:`changelog_tab_${d}`,page:"changelog",tab:_}),g({page:"changelog",tab:_}),r.setStatusFilter(d),r.setOffset(0)},rightActions:e.jsx("button",{className:N.clearButton,onClick:()=>{i("dashboard_click_event",{click_target:"changelog_clear",page:"changelog",tab:`changelog_${r.statusFilter}`}),y(!0)},children:t("common.clear","Clear")})}),r.loading&&r.entries.length===0&&e.jsx("div",{className:N.loading,children:t("common.loading","Loading...")}),!r.loading&&r.entries.length===0?e.jsx("div",{className:N.empty,children:t("changelog.empty","No changelog entries for the current place yet")}):e.jsx("div",{className:N.list,children:k.map(d=>e.jsx(Be,{entry:d,onClick:_=>R(d.entryId,_),buttonRef:_=>{d.entryId===f&&_&&($.current=_)}},d.entryId))}),w&&e.jsxs("div",{className:N.pagination,children:[e.jsx("button",{className:N.btn,disabled:r.offset===0,onClick:()=>r.setOffset(Math.max(0,r.offset-V)),children:t("tools.page.prev","Prev")}),e.jsxs("span",{className:N.pageInfo,children:[r.offset+1,"–",Math.min(r.offset+V,r.total)," / ",r.total]}),e.jsx("button",{className:N.btn,disabled:!r.hasMore,onClick:()=>r.setOffset(r.offset+V),children:t("tools.page.next","Next")})]}),S&&e.jsx(e.Fragment,{children:e.jsxs("div",{className:N.limitNotice,children:[e.jsxs("div",{className:N.limitNoticeContent,children:[e.jsx("div",{className:N.limitNoticeTitle,children:t("changelog.basic.limit.title","Basic preview shows the latest 3 sessions")}),e.jsx("div",{className:N.limitNoticeText,children:t("changelog.basic.limit.body","Full changelog timeline browsing is available with Pro.")})]}),e.jsx("a",{className:N.primaryAction,href:ne.changelog,target:"_blank",rel:"noreferrer",onClick:()=>i("dashboard_click_event",{click_target:"upgrade_cta",placement:"changelog_limit_notice",page:"changelog",tab:`changelog_${r.statusFilter}`}),children:t("tier.upgrade","View Pro")})]})}),e.jsx(ie,{open:L,title:t("changelog.clear.title","Clear changelog?"),message:t("changelog.clear.message","This permanently removes the stored changelog for the current place."),cancelLabel:t("common.cancel","Cancel"),confirmLabel:t("common.clear","Clear"),loading:E,onCancel:()=>!E&&y(!1),onConfirm:A}),f&&e.jsx(Mt,{entryId:f,placeId:u,onClose:M,returnFocusTo:$.current})]})}export{mn as Component};
@@ -1 +1 @@
1
- import{r as u,j as s}from"./index-CACN5u4J.js";import{s as a}from"./ConfirmModal.module-DJksQHBd.js";function p({open:r,title:t,message:o,cancelLabel:c,confirmLabel:n,loading:e=!1,onCancel:l,onConfirm:d}){const i=u.useId();return r?s.jsx("div",{className:a.backdrop,onClick:e?void 0:l,children:s.jsxs("div",{className:a.modal,role:"dialog","aria-modal":"true","aria-labelledby":i,onClick:m=>m.stopPropagation(),children:[s.jsx("h2",{id:i,className:a.title,children:t}),s.jsx("p",{className:a.message,children:o}),s.jsxs("div",{className:a.actions,children:[s.jsx("button",{className:a.cancelButton,onClick:l,disabled:e,children:c}),s.jsx("button",{className:a.confirmButton,onClick:d,disabled:e,children:e?"...":n})]})]})}):null}export{p as C};
1
+ import{r as u,j as s}from"./index-Ygt1Wh6v.js";import{s as a}from"./ConfirmModal.module-DJksQHBd.js";function p({open:r,title:t,message:o,cancelLabel:c,confirmLabel:n,loading:e=!1,onCancel:l,onConfirm:d}){const i=u.useId();return r?s.jsx("div",{className:a.backdrop,onClick:e?void 0:l,children:s.jsxs("div",{className:a.modal,role:"dialog","aria-modal":"true","aria-labelledby":i,onClick:m=>m.stopPropagation(),children:[s.jsx("h2",{id:i,className:a.title,children:t}),s.jsx("p",{className:a.message,children:o}),s.jsxs("div",{className:a.actions,children:[s.jsx("button",{className:a.cancelButton,onClick:l,disabled:e,children:c}),s.jsx("button",{className:a.confirmButton,onClick:d,disabled:e,children:e?"...":n})]})]})}):null}export{p as C};
@@ -1,4 +1,4 @@
1
- import{i as te,u as oe,r as d,j as e,f as ie,a as F,D as ce,L as le,M as ae,k as V,e as re,l as de,s as ge}from"./index-CACN5u4J.js";import{I as u}from"./InfoLabel-Cf_fu0ZE.js";import{P as pe}from"./PageHeader-CTOJDcG8.js";import{S as ne}from"./StatusBadge-DPEvJdzm.js";import{T as X}from"./TooltipText-55u9HaGy.js";import{C as J}from"./ConfirmModal-CyjUVYwz.js";import{f as se,u as ue}from"./useLiveUptime-kOkM_pqk.js";import{C as q}from"./copy-szgBQciT.js";import"./UiPrimitive-BUpeGXNh.js";import"./ConfirmModal.module-DJksQHBd.js";/**
1
+ import{f as te,u as oe,r as d,j as e,d as ie,b as F,D as ce,L as le,M as ae,h as V,a as re,i as de,s as ge}from"./index-Ygt1Wh6v.js";import{I as u}from"./InfoLabel-D6WxKFnG.js";import{P as pe}from"./PageHeader-Xrn6BpcL.js";import{S as ne}from"./StatusBadge-Ddzg1cSk.js";import{T as X}from"./TooltipText-B1An7dUI.js";import{C as J}from"./ConfirmModal-BSbhJt6x.js";import{f as se,u as ue}from"./useLiveUptime-CnfGQ_vS.js";import{C as q}from"./copy-B03ftJiE.js";import"./ConfirmModal.module-DJksQHBd.js";/**
2
2
  * @license lucide-react v1.8.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -8,4 +8,4 @@ import{i as te,u as oe,r as d,j as e,f as ie,a as F,D as ce,L as le,M as ae,k as
8
8
  *
9
9
  * This source code is licensed under the ISC license.
10
10
  * See the LICENSE file in the root directory of this source tree.
11
- */const me=[["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"}]],xe=te("server",me),_e="_container_1h084_2",Se="_entry_1h084_14",je="_timestamp_1h084_21",ve="_message_1h084_27",ke="_warn_1h084_34",fe="_error_1h084_39",be="_empty_1h084_44",W={container:_e,entry:Se,timestamp:je,message:ve,warn:ke,error:fe,empty:be};function Ce(t){const s=new Date(t);return Number.isNaN(s.getTime())?t:`${String(s.getHours()).padStart(2,"0")}:${String(s.getMinutes()).padStart(2,"0")}`}function Ne({entries:t}){const{t:s}=oe(),n=d.useRef(null);return d.useEffect(()=>{const l=n.current;l&&(l.scrollTop=l.scrollHeight)},[t.length]),e.jsx("div",{ref:n,className:W.container,children:t.length===0?e.jsx("div",{className:W.empty,children:s("connection.log.empty","No events yet")}):t.map((l,i)=>e.jsxs("div",{className:`${W.entry} ${l.type?W[l.type]:""}`,children:[e.jsx("span",{className:W.timestamp,children:Ce(l.timestamp)}),e.jsx("span",{className:W.message,children:l.message})]},i))})}const Q=50;function we(){const t=new Date;return`${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`}function Ie(){const{level:t,status:s,error:n}=ie(),[l,i]=d.useState(null),[y,g]=d.useState(null),[c,w]=d.useState([]),b=d.useRef(null),A=d.useCallback((p,j)=>{w(N=>{const S=[...N,{timestamp:we(),message:p,type:j}];return S.length>Q?S.slice(-Q):S})},[]),m=d.useCallback(async()=>{try{const p=await F.get("/connection-info");i(p)}catch{i(null)}},[]),P=d.useCallback(async()=>{try{const p=await F.get("/api/dashboard/studio-routing");g(p)}catch{g(null)}},[]),I=d.useCallback(async p=>{const j=await F.patch("/api/dashboard/studio-routing",p);return g(j),await m(),j},[m]),M=d.useCallback(async()=>{try{const p=await F.get("/api/dashboard/connection-log");w(p.entries??[])}catch{w([])}},[]),H=d.useCallback(async()=>{await F.post("/api/dashboard/connection-log/clear"),w([])},[]),C=d.useCallback(async p=>{await F.post("/api/dashboard/kill-agent",{instanceId:p}),await m()},[m]);return d.useEffect(()=>{t!=="disconnected"&&s?(m(),P()):g(null),M()},[t,s,m,M,P]),d.useEffect(()=>{const p=new ce;b.current=p,p.connect();const j=p.on("connection",S=>{const h=S;h.status!=="updated"&&h.clientId&&A(`Plugin ${h.status} — ${h.clientId}`,h.status==="disconnected"?"warn":"info"),m(),P()}),N=p.on("mcp_status",S=>{const h=S,z=h.status==="registered"?"registered":"unregistered";A(`MCP ${z} — ${h.aiClientName}`,h.status==="registered"?"info":"warn"),m(),P()});return()=>{j(),N(),p.disconnect(),b.current=null}},[A,m,P]),{status:s,connectionInfo:l,studioRouting:y,connectionLog:c,level:t,error:n,clearConnectionLog:H,killAgent:C,updateStudioRouting:I}}const Le="_page_14kg9_2",Ae="_card_14kg9_11",Pe="_topologyCard_14kg9_19",Be="_topologyDisconnected_14kg9_26",$e="_topologyHeader_14kg9_30",Me="_topologyIntro_14kg9_38",Ee="_topologyNetwork_14kg9_45",Te="_topologyLinks_14kg9_49",He="_topologyLink_14kg9_49",De="_topologyLink_agent_14kg9_66",Ue="_topologyLink_studio_14kg9_70",Oe="_topologyGrid_14kg9_74",Fe="_topologyColumn_14kg9_83",We="_topologyColumnHeader_14kg9_90",ze="_topologyColumnHeaderSpacer_14kg9_101",Ye="_topologyCount_14kg9_105",Ve="_topologyList_14kg9_120",Ge="_topologyListCentered_14kg9_128",qe="_topologyNode_14kg9_132",Re="_topologyNodeTitle_14kg9_140",Ke="_topologyNodeMeta_14kg9_156",Xe="_topologyNodeSubtle_14kg9_157",Je="_topologyState_14kg9_170",Qe="_topologyEmpty_14kg9_183",Ze="_topologyOverflow_14kg9_198",et="_topologyOverflowButton_14kg9_213",tt="_topologyServerColumn_14kg9_236",ot="_topologyServer_14kg9_236",nt="_topologyServerIcon_14kg9_254",st="_topologyServerBody_14kg9_267",it="_topologyServerTitle_14kg9_276",ct="_topologyServerMeta_14kg9_283",lt="_routingSummaryCompact_14kg9_290",at="_disabled_14kg9_298",rt="_cardHeader_14kg9_304",dt="_cardHint_14kg9_317",gt="_clearButton_14kg9_324",pt="_serverGrid_14kg9_348",ut="_statusRow_14kg9_366",ht="_metaItem_14kg9_373",yt="_table_14kg9_380",mt="_tableWrap_14kg9_400",xt="_routingSummary_14kg9_290",_t="_manageLink_14kg9_416",St="_segment_14kg9_442",jt="_segmentActive_14kg9_443",vt="_targetPrimary_14kg9_477",kt="_monoMuted_14kg9_481",ft="_copyIconButton_14kg9_485",bt="_routingBadge_14kg9_510",Ct="_studioStateBadge_14kg9_524",Nt="_studioState_running_14kg9_539",wt="_studioState_paused_14kg9_545",It="_studioState_edit_14kg9_551",Lt="_studioState_unknown_14kg9_557",At="_toggleBtn_14kg9_564",Pt="_disconnected_14kg9_579",Bt="_disconnectedActions_14kg9_596",$t="_btn_14kg9_603",Mt="_activity_active_14kg9_621",Et="_activity_stale_14kg9_622",Tt="_activity_unknown_14kg9_623",Ht="_killBtn_14kg9_647",Dt="_emptyRow_14kg9_671",o={page:Le,card:Ae,topologyCard:Pe,topologyDisconnected:Be,topologyHeader:$e,topologyIntro:Me,topologyNetwork:Ee,topologyLinks:Te,topologyLink:He,topologyLink_agent:De,topologyLink_studio:Ue,topologyGrid:Oe,topologyColumn:Fe,topologyColumnHeader:We,topologyColumnHeaderSpacer:ze,topologyCount:Ye,topologyList:Ve,topologyListCentered:Ge,topologyNode:qe,topologyNodeTitle:Re,topologyNodeMeta:Ke,topologyNodeSubtle:Xe,topologyState:Je,topologyEmpty:Qe,topologyOverflow:Ze,topologyOverflowButton:et,topologyServerColumn:tt,topologyServer:ot,topologyServerIcon:nt,topologyServerBody:st,topologyServerTitle:it,topologyServerMeta:ct,routingSummaryCompact:lt,disabled:at,cardHeader:rt,cardHint:dt,clearButton:gt,serverGrid:pt,statusRow:ut,metaItem:ht,table:yt,tableWrap:mt,routingSummary:xt,manageLink:_t,segment:St,segmentActive:jt,targetPrimary:vt,monoMuted:kt,copyIconButton:ft,routingBadge:bt,studioStateBadge:Ct,studioState_running:Nt,studioState_paused:wt,studioState_edit:It,studioState_unknown:Lt,toggleBtn:At,disconnected:Pt,disconnectedActions:Bt,btn:$t,activity_active:Mt,activity_stale:Et,activity_unknown:Tt,killBtn:Ht,emptyRow:Dt},G=5;function Ut(t){return t?Date.now()-t<3e4?"active":"stale":"unknown"}function Ot(t,s){return t==="active"?s("connection.topology.active","Active"):t==="stale"?s("connection.topology.stale","Stale"):s("connection.topology.unknown","Unknown")}function Z(t){return t.length>10?t.slice(0,10):t}function ee(t,s){return t.replace("{count}",String(s))}function Ft(t,s,n){const l=t.studioState??"unknown",i={edit:s("connection.targets.studioState.edit","Edit"),running:s("connection.targets.studioState.running","Running"),paused:s("connection.targets.studioState.paused","Paused"),unknown:s("connection.targets.studioState.unknown","Unknown")},y=t.studioStateSource==="thread"?s("connection.targets.studioState.source.thread","WEPPY play command"):t.studioStateSource==="pluginConnection"?s("connection.targets.studioState.source.pluginConnection","Studio Play/Test connection"):t.studioStateSource==="runService"?s("connection.targets.studioState.source.runService","Studio RunService"):s("connection.targets.studioState.source.unknown","Unknown source"),g=t.studioStateUpdatedAt?n(t.studioStateUpdatedAt):s("connection.targets.studioState.updatedUnknown","not reported");return{state:l,label:i[l],tooltip:`${y} · ${g}`}}function Wt(t,s){return t.length!==s.length?!1:t.every((n,l)=>{const i=s[l];return i!==void 0&&n.id===i.id&&n.side===i.side&&Math.abs(n.x1-i.x1)<.5&&Math.abs(n.y1-i.y1)<.5&&Math.abs(n.x2-i.x2)<.5&&Math.abs(n.y2-i.y2)<.5})}function f(t,s,n){return{x:s-t.left,y:n-t.top}}function zt(t,s,n,l){if(s.right<=n.left){const g=f(l,s.right,s.top+s.height/2),c=f(l,n.left,n.top+n.height/2);return{id:t,side:"agent",x1:g.x,y1:g.y,x2:c.x,y2:c.y}}if(s.bottom<=n.top){const g=f(l,s.left+s.width/2,s.bottom),c=f(l,n.left+n.width/2,n.top);return{id:t,side:"agent",x1:g.x,y1:g.y,x2:c.x,y2:c.y}}const i=f(l,s.left+s.width/2,s.top),y=f(l,n.left+n.width/2,n.bottom);return{id:t,side:"agent",x1:i.x,y1:i.y,x2:y.x,y2:y.y}}function Yt(t,s,n,l){if(n.right<=s.left){const g=f(l,s.left,s.top+s.height/2),c=f(l,n.right,n.top+n.height/2);return{id:t,side:"studio",x1:g.x,y1:g.y,x2:c.x,y2:c.y}}if(n.bottom<=s.top){const g=f(l,s.left+s.width/2,s.top),c=f(l,n.left+n.width/2,n.bottom);return{id:t,side:"studio",x1:g.x,y1:g.y,x2:c.x,y2:c.y}}const i=f(l,s.left+s.width/2,s.bottom),y=f(l,n.left+n.width/2,n.top);return{id:t,side:"studio",x1:i.x,y1:i.y,x2:y.x,y2:y.y}}function Vt({agents:t,isDisconnected:s,pinnedTargetClientId:n,priorityTarget:l,status:i,studioRoutingMode:y,studioTargets:g,t:c,timeAgo:w,onCopySelector:b,onManageRouting:A}){const[m,P]=d.useState(!1),[I,M]=d.useState(!1),[H,C]=d.useState([]),p=d.useRef(null),j=d.useRef(null),N=d.useRef(new Map),S=d.useRef(new Map),h=y==="pinned"?c("connection.routing.pinned","Manual: Pinned Studio"):c("connection.routing.recentPriority","Automatic: Recent priority"),z=s?"offline":"online",k=d.useMemo(()=>m?t:t.slice(0,G),[t,m]),D=Math.max(0,t.length-k.length),v=d.useMemo(()=>I?g:g.slice(0,G),[g,I]),E=Math.max(0,g.length-v.length),R=[o.topologyList,k.length<=1?o.topologyListCentered:""].filter(Boolean).join(" "),K=[o.topologyList,v.length<=1?o.topologyListCentered:""].filter(Boolean).join(" "),U=d.useCallback(a=>x=>{if(x){N.current.set(a,x);return}N.current.delete(a)},[]),r=d.useCallback(a=>x=>{if(x){S.current.set(a,x);return}S.current.delete(a)},[]),L=d.useCallback(()=>{const a=p.current,x=j.current;if(!a||!x){C([]);return}const _=a.getBoundingClientRect(),B=x.getBoundingClientRect(),O=[];k.forEach($=>{const Y=N.current.get($.instanceId);Y&&O.push(zt(`agent-${$.instanceId}`,Y.getBoundingClientRect(),B,_))}),v.forEach($=>{const Y=S.current.get($.clientId);Y&&O.push(Yt(`studio-${$.clientId}`,Y.getBoundingClientRect(),B,_))}),C($=>Wt($,O)?$:O)},[k,v]);return d.useLayoutEffect(()=>{L();const a=[p.current,j.current,...k.map(_=>N.current.get(_.instanceId)),...v.map(_=>S.current.get(_.clientId))].filter(_=>_!=null);if(window.addEventListener("resize",L),typeof ResizeObserver>"u")return()=>{window.removeEventListener("resize",L)};const x=new ResizeObserver(L);return a.forEach(_=>x.observe(_)),()=>{window.removeEventListener("resize",L),x.disconnect()}},[L,k,v]),e.jsxs("section",{className:`${o.topologyCard} ${s?o.topologyDisconnected:""}`,"aria-label":c("connection.topology.ariaLabel","Connection topology"),children:[e.jsxs("div",{className:o.topologyHeader,children:[e.jsxs("div",{children:[e.jsx("div",{className:o.cardHeader,children:c("connection.topology.title","Connection topology")}),e.jsx("p",{className:o.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(le,{to:"/controls?section=studio-routing",className:o.manageLink,onClick:A,children:c("connection.routing.manage","Manage routing")})]}),e.jsxs("div",{className:o.topologyNetwork,ref:p,children:[e.jsx("svg",{"aria-hidden":"true",className:o.topologyLinks,"data-testid":"topology-connection-lines",focusable:"false",children:H.map(a=>e.jsx("line",{className:`${o.topologyLink} ${o[`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:o.topologyGrid,children:[e.jsxs("div",{className:o.topologyColumn,children:[e.jsxs("div",{className:o.topologyColumnHeader,children:[e.jsx(ye,{size:15,"aria-hidden":"true"}),e.jsx("span",{children:c("connection.agents.title","AI Agents")}),e.jsx("span",{className:o.topologyCount,children:t.length})]}),e.jsxs("div",{className:R,children:[t.length>0?k.map(a=>{const x=Ut(a.lastSeen),_=a.aiClientName??Z(a.instanceId),B=a.lastSeen??a.lastCommandAt??a.connectedAt,O=a.mcpVersion?`${c("connection.topology.adapterRole","MCP Adapter")} v${a.mcpVersion}`:c("connection.topology.adapterRole","MCP Adapter");return e.jsxs("div",{className:o.topologyNode,ref:U(a.instanceId),children:[e.jsxs("div",{className:o.topologyNodeTitle,children:[e.jsx("span",{className:o[`activity_${x}`]}),e.jsx("strong",{children:_}),e.jsx("span",{className:o.topologyState,children:Ot(x,c)})]}),e.jsxs("div",{className:o.topologyNodeMeta,children:[e.jsx("span",{children:O})," ·"," ",c("connection.server.session","Session")," ",Z(a.instanceId)," ·"," ",B?`${c("connection.topology.lastActivity","Last activity")} ${w(B)}`:c("connection.topology.noActivity","No recent activity")]})]},a.instanceId)}):e.jsx("div",{className:o.topologyEmpty,children:c("connection.agents.none","No agents connected")}),t.length>G?e.jsxs("div",{className:o.topologyOverflow,children:[D>0?e.jsx("span",{children:ee(c("connection.topology.moreAgents","+{count} more agents"),D)}):e.jsx("span",{children:c("connection.topology.allAgentsVisible","All agents visible")}),e.jsx("button",{type:"button",className:o.topologyOverflowButton,"aria-label":m?c("connection.topology.showLessAgents","Show less AI agents"):c("connection.topology.showAllAgents","Show all AI agents"),onClick:()=>P(a=>!a),children:m?c("connection.topology.showLess","Show less"):c("connection.topology.showAll","Show all")})]}):null]})]}),e.jsxs("div",{className:o.topologyServerColumn,children:[e.jsx("div",{className:o.topologyColumnHeaderSpacer,"aria-hidden":"true"}),e.jsxs("div",{className:`${o.topologyNode} ${o.topologyServer}`,ref:j,children:[e.jsx("div",{className:o.topologyServerIcon,children:e.jsx(xe,{size:18,"aria-hidden":"true"})}),e.jsxs("div",{className:o.topologyServerBody,children:[e.jsx("div",{className:o.topologyServerTitle,children:c("connection.topology.serverTitle","WEPPY Bridge")}),e.jsx(ne,{status:z}),e.jsxs("div",{className:o.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:o.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")} ${se(i.uptime)}`}):null]}):null,e.jsx("div",{className:o.routingSummaryCompact,children:e.jsx("span",{className:o.routingBadge,children:h})})]})]})]}),e.jsxs("div",{className:o.topologyColumn,children:[e.jsxs("div",{className:o.topologyColumnHeader,children:[e.jsx(ae,{size:15,"aria-hidden":"true"}),e.jsx("span",{children:c("connection.targets.title","Studio Targets")}),e.jsx("span",{className:o.topologyCount,children:g.length})]}),e.jsxs("div",{className:K,children:[g.length>0?v.map(a=>{const x=y==="pinned"&&n===a.clientId,_=y==="recentPriority"&&(l==null?void 0:l.clientId)===a.clientId,B=Ft(a,c,w);return e.jsxs("div",{className:o.topologyNode,ref:r(a.clientId),children:[e.jsxs("div",{className:o.topologyNodeTitle,children:[e.jsx("span",{className:o.targetPrimary,children:a.targetAlias}),e.jsx(V,{text:c("connection.targets.copyTargetAlias","Copy Studio ID"),children:e.jsx("button",{type:"button",className:o.copyIconButton,"aria-label":c("connection.targets.copyTargetAlias","Copy Studio ID"),onClick:()=>b(a.targetAlias,"target_alias"),children:e.jsx(q,{size:13,"aria-hidden":"true"})})}),x?e.jsx("span",{className:o.routingBadge,children:c("connection.routing.pinnedBadge","Pinned")}):_?e.jsx("span",{className:o.routingBadge,children:c("connection.routing.priorityBadge","Priority")}):null,e.jsx(V,{text:B.tooltip,children:e.jsx("span",{className:`${o.studioStateBadge} ${o[`studioState_${B.state}`]}`,children:B.label})})]}),e.jsxs("div",{className:o.topologyNodeMeta,children:[e.jsx("span",{children:a.placeName??c("connection.topology.placeUnknown","Place unknown")}),a.placeId!==void 0?` · ${a.placeId}`:""]}),e.jsxs("div",{className:o.topologyNodeSubtle,children:[a.connectionState," · ",c("connection.targets.lastSeen","Last Seen")," ",w(a.lastSeen)]})]},a.clientId)}):e.jsx("div",{className:o.topologyEmpty,children:c("connection.targets.none","No Studio targets connected. Open Roblox Studio and connect WEPPY Plugin.")}),g.length>G?e.jsxs("div",{className:o.topologyOverflow,children:[E>0?e.jsx("span",{children:ee(c("connection.topology.moreStudios","+{count} more studios"),E)}):e.jsx("span",{children:c("connection.topology.allStudiosVisible","All studios visible")}),e.jsx("button",{type:"button",className:o.topologyOverflowButton,"aria-label":I?c("connection.topology.showLessStudios","Show less Studio targets"):c("connection.topology.showAllStudios","Show all Studio targets"),onClick:()=>M(a=>!a),children:I?c("connection.topology.showLess","Show less"):c("connection.topology.showAll","Show all")})]}):null]})]})]})]})]})}function T(t,s){const n=Math.max(0,Math.floor((Date.now()-t)/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 Gt(t){return t?Date.now()-t<3e4?"active":"stale":"unknown"}function qt(t,s){const n=t.studioState??"unknown",l={edit:s("connection.targets.studioState.edit","Edit"),running:s("connection.targets.studioState.running","Running"),paused:s("connection.targets.studioState.paused","Paused"),unknown:s("connection.targets.studioState.unknown","Unknown")},i=t.studioStateSource==="thread"?s("connection.targets.studioState.source.thread","WEPPY play command"):t.studioStateSource==="pluginConnection"?s("connection.targets.studioState.source.pluginConnection","Studio Play/Test connection"):t.studioStateSource==="runService"?s("connection.targets.studioState.source.runService","Studio RunService"):s("connection.targets.studioState.source.unknown","Unknown source"),y=t.studioStateUpdatedAt?T(t.studioStateUpdatedAt,s):s("connection.targets.studioState.updatedUnknown","not reported"),g=t.playtestMode&&t.playtestMode!=="unknown"?` · ${t.playtestMode}`:"";return{state:n,label:`${l[n]}${g}`,tooltip:`${i} · ${y}`}}function so(){const{t}=oe(),{trackEvent:s}=re(),{status:n,connectionInfo:l,studioRouting:i,connectionLog:y,level:g,clearConnectionLog:c,killAgent:w}=Ie(),{show:b}=de(),[A,m]=d.useState(!0),[P,I]=d.useState(!1),[M,H]=d.useState(!1),[C,p]=d.useState(null),[j,N]=d.useState(!1),S=ue(n==null?void 0:n.uptime),h=g==="disconnected",z=h?"offline":"online",k=(i==null?void 0:i.studioRoutingMode)??(n==null?void 0:n.studioRoutingMode)??"recentPriority",D=(i==null?void 0:i.pinnedTargetClientId)??(n==null?void 0:n.pinnedTargetClientId)??null,v=ge((i==null?void 0:i.targets)??(n==null?void 0:n.pluginClients)??[],k,D),E=(i==null?void 0:i.priorityTarget)??v[0],R=async()=>{if(C){N(!0);try{await w(C.instanceId),b(t("connection.agents.killed","Agent killed"),"success"),p(null)}catch{b(t("connection.agents.killFailed","Failed to kill agent"),"error")}finally{N(!1)}}},K=async()=>{H(!0);try{await c(),b(t("toast.clearSuccess","Cleared successfully"),"success"),I(!1)}catch{b(t("toast.clearFailed","Failed to clear data"),"error")}finally{H(!1)}},U=async(r,L)=>{try{await navigator.clipboard.writeText(r),b(t("connection.targets.copied","Copied value"),"success"),s("dashboard_click_event",{click_target:`connection_copy_${L}`,page:"connection"})}catch{b(t("connection.targets.copyFailed","Failed to copy value"),"error")}};return e.jsxs("div",{className:o.page,children:[e.jsx(pe,{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:g}}),e.jsx(Vt,{agents:(l==null?void 0:l.mcpInstances)??[],isDisconnected:h,pinnedTargetClientId:D,priorityTarget:E,status:n??null,studioRoutingMode:k,studioTargets:v,t,timeAgo:r=>T(r,t),onCopySelector:U,onManageRouting:()=>s("dashboard_click_event",{click_target:"connection_manage_routing",page:"connection"})}),e.jsxs("div",{className:o.card,children:[e.jsx("div",{className:o.cardHeader,children:t("connection.server.title","Bridge Status")}),h?e.jsxs("div",{className:o.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:o.disconnectedActions,children:[e.jsx("button",{className:o.btn,onClick:()=>window.location.reload(),children:t("connection.reconnect","Reconnect")}),e.jsx("button",{className:o.btn,onClick:()=>{window.location.hash="#/settings"},children:t("connection.checkSettings","Check Settings")})]})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:o.statusRow,children:e.jsx(ne,{status:z})}),e.jsxs("dl",{className:o.serverGrid,children:[(n==null?void 0:n.version)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(u,{label:t("connection.server.version","Version"),tooltip:t("connection.server.version.tooltip","WEPPY Bridge runtime version")})}),e.jsx("dd",{children:e.jsx(X,{text:t("connection.server.version.tooltip","WEPPY Bridge runtime version"),children:`v${n.version}`})})]}),(n==null?void 0:n.pid)!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(u,{label:t("connection.server.pid","PID"),tooltip:t("connection.server.pid.tooltip","Operating system process identifier")})}),e.jsx("dd",{children:n.pid})]}),(n==null?void 0:n.uptime)!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(u,{label:t("connection.server.uptime","Uptime"),tooltip:t("connection.server.uptime.tooltip","Time elapsed since the WEPPY Bridge started")})}),e.jsx("dd",{children:se(S??n.uptime)})]}),(n==null?void 0:n.sessionId)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(u,{label:t("connection.server.session","Session"),tooltip:t("connection.server.session.tooltip","Current WEPPY Bridge session identifier")})}),e.jsx("dd",{children:n.sessionId.slice(0,8)})]}),(l==null?void 0:l.serverExecutable)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(u,{label:t("connection.server.exec","Exec"),tooltip:t("connection.server.exec.tooltip","Executable path used to launch the WEPPY Bridge")})}),e.jsx("dd",{children:l.serverExecutable})]})]})]})]}),e.jsxs("div",{className:`${o.card} ${h?o.disabled:""}`,children:[e.jsxs("div",{className:o.cardHeader,children:[e.jsxs("span",{children:[t("connection.agents.title","AI Agents")," ","(",(l==null?void 0:l.mcpInstanceCount)??0,")"]}),e.jsx("button",{className:o.toggleBtn,onClick:()=>m(r=>!r),"aria-label":A?t("common.collapse","Collapse"):t("common.expand","Expand"),children:A?"▾":"▸"})]}),A&&e.jsxs("table",{className:o.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(u,{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(u,{label:t("connection.server.pid","PID"),tooltip:t("connection.server.pid.tooltip","Operating system process identifier")})}),e.jsx("th",{children:e.jsx(u,{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(u,{label:t("connection.agents.lastSeen","Last Seen"),tooltip:t("connection.agents.lastSeen.tooltip","Most recent heartbeat or activity from this agent")})}),e.jsx("th",{children:e.jsx(u,{label:t("connection.agents.lastCommand","Last Command"),tooltip:t("connection.agents.lastCommand.tooltip","Most recent tool call executed by this agent")})}),e.jsx("th",{})]})}),e.jsx("tbody",{children:l!=null&&l.mcpInstances&&l.mcpInstances.length>0?l.mcpInstances.map(r=>e.jsxs("tr",{children:[e.jsxs("td",{children:[e.jsx("span",{className:o[`activity_${Gt(r.lastSeen)}`]}),r.aiClientName??t("connection.agents.unknown","Unknown")]}),e.jsx("td",{children:r.mcpVersion??"-"}),e.jsx("td",{children:r.pid}),e.jsx("td",{children:r.projectRoot??r.cwd??t("connection.agents.projectRoot.unresolved","Unresolved")}),e.jsx("td",{children:T(r.connectedAt,t)}),e.jsx("td",{children:r.lastSeen?T(r.lastSeen,t):"-"}),e.jsx("td",{children:r.lastCommandAt?T(r.lastCommandAt,t):"-"}),e.jsx("td",{children:!r.isServer&&e.jsx("button",{className:o.killBtn,onClick:()=>{s("dashboard_click_event",{click_target:"connection_kill_agent",page:"connection"}),p({instanceId:r.instanceId,name:r.aiClientName??r.instanceId.slice(0,8)})},children:t("connection.agents.kill","Kill")})})]},r.instanceId)):e.jsx("tr",{children:e.jsx("td",{colSpan:8,className:o.emptyRow,children:t("connection.agents.none","No agents connected")})})})]})]}),e.jsxs("div",{className:`${o.card} ${h?o.disabled:""}`,children:[e.jsxs("div",{className:o.cardHeader,children:[t("connection.targets.title","Studio Targets")," ","(",v.length,")"]}),e.jsx("p",{className:o.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:o.tableWrap,children:e.jsxs("table",{className:o.table,children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:e.jsx(u,{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(u,{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(u,{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(u,{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(u,{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(u,{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(u,{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(u,{label:t("connection.targets.version","Version"),tooltip:t("connection.targets.version.tooltip","Installed plugin version reported by Studio")})}),e.jsx("th",{children:e.jsx(u,{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(u,{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:v.length>0?v.map(r=>{const L=r.clientId.slice(0,10),a=qt(r,t);return e.jsxs("tr",{children:[e.jsxs("td",{children:[e.jsx("span",{className:o.monoMuted,title:r.clientId,children:r.targetAlias}),e.jsx(V,{text:t("connection.targets.copyTargetAlias","Copy Studio ID"),children:e.jsx("button",{type:"button",className:o.copyIconButton,"aria-label":t("connection.targets.copyTargetAlias","Copy Studio ID"),onClick:()=>U(r.targetAlias,"target_alias"),children:e.jsx(q,{size:13,"aria-hidden":"true"})})})]}),e.jsx("td",{children:e.jsx("span",{className:o.targetPrimary,children:r.placeName??"-"})}),e.jsxs("td",{children:[r.placeId??"-",r.placeId!==void 0?e.jsx(V,{text:t("connection.targets.copyPlaceId","Copy Place ID"),children:e.jsx("button",{type:"button",className:o.copyIconButton,"aria-label":t("connection.targets.copyPlaceId","Copy Place ID"),onClick:()=>U(String(r.placeId),"place_id"),children:e.jsx(q,{size:13,"aria-hidden":"true"})})}):null]}),e.jsxs("td",{children:[e.jsx("span",{className:o.monoMuted,title:r.clientId,children:L}),e.jsx(V,{text:t("connection.targets.copyClientId","Copy Connection ID"),children:e.jsx("button",{type:"button",className:o.copyIconButton,"aria-label":t("connection.targets.copyClientId","Copy Connection ID"),onClick:()=>U(r.clientId,"client_id"),children:e.jsx(q,{size:13,"aria-hidden":"true"})})})]}),e.jsx("td",{children:e.jsx(X,{text:a.tooltip,children:e.jsx("span",{className:`${o.studioStateBadge} ${o[`studioState_${a.state}`]}`,children:a.label})})}),e.jsx("td",{children:r.connectionState}),e.jsx("td",{children:r.lastRoutedAt?T(r.lastRoutedAt,t):"-"}),e.jsx("td",{children:T(r.lastSeen,t)}),e.jsx("td",{children:r.pluginVersion??"-"}),e.jsx("td",{children:k==="pinned"&&D===r.clientId?e.jsx("span",{className:o.routingBadge,children:t("connection.routing.pinnedBadge","Pinned")}):k==="recentPriority"&&(E==null?void 0:E.clientId)===r.clientId?e.jsx("span",{className:o.routingBadge,children:t("connection.routing.priorityBadge","Priority")}):e.jsx("span",{className:o.monoMuted,children:"-"})}),e.jsx("td",{children:r.inFlightRequestId?r.inFlightRequestId.slice(0,8):"-"})]},r.clientId)}):e.jsx("tr",{children:e.jsx("td",{colSpan:11,className:o.emptyRow,children:t("connection.targets.none","No Studio targets connected. Open Roblox Studio and connect WEPPY Plugin.")})})})]})})]}),e.jsxs("div",{className:`${o.card} ${h?o.disabled:""}`,children:[e.jsxs("div",{className:o.cardHeader,children:[e.jsx("span",{children:t("connection.log.title","Connection Log")}),e.jsx("button",{className:o.clearButton,onClick:()=>{s("dashboard_click_event",{click_target:"connection_clear_log",page:"connection"}),I(!0)},children:t("common.clear","Clear")})]}),e.jsx(Ne,{entries:y})]}),e.jsx(J,{open:P,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:M,onCancel:()=>!M&&I(!1),onConfirm:K}),e.jsx(J,{open:!!C,title:t("connection.agents.kill.title","Kill agent?"),message:`"${C==null?void 0:C.name}" 프로세스를 강제 종료합니다. 해당 에이전트의 진행 중인 작업이 중단됩니다.`,cancelLabel:t("common.cancel","Cancel"),confirmLabel:t("connection.agents.kill","Kill"),loading:j,onCancel:()=>!j&&p(null),onConfirm:R})]})}export{so as Component};
11
+ */const me=[["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"}]],xe=te("server",me),_e="_container_1h084_2",Se="_entry_1h084_14",je="_timestamp_1h084_21",ve="_message_1h084_27",ke="_warn_1h084_34",fe="_error_1h084_39",be="_empty_1h084_44",W={container:_e,entry:Se,timestamp:je,message:ve,warn:ke,error:fe,empty:be};function Ce(t){const s=new Date(t);return Number.isNaN(s.getTime())?t:`${String(s.getHours()).padStart(2,"0")}:${String(s.getMinutes()).padStart(2,"0")}`}function Ne({entries:t}){const{t:s}=oe(),n=d.useRef(null);return d.useEffect(()=>{const l=n.current;l&&(l.scrollTop=l.scrollHeight)},[t.length]),e.jsx("div",{ref:n,className:W.container,children:t.length===0?e.jsx("div",{className:W.empty,children:s("connection.log.empty","No events yet")}):t.map((l,i)=>e.jsxs("div",{className:`${W.entry} ${l.type?W[l.type]:""}`,children:[e.jsx("span",{className:W.timestamp,children:Ce(l.timestamp)}),e.jsx("span",{className:W.message,children:l.message})]},i))})}const Q=50;function we(){const t=new Date;return`${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`}function Ie(){const{level:t,status:s,error:n}=ie(),[l,i]=d.useState(null),[y,g]=d.useState(null),[c,w]=d.useState([]),b=d.useRef(null),A=d.useCallback((p,j)=>{w(N=>{const S=[...N,{timestamp:we(),message:p,type:j}];return S.length>Q?S.slice(-Q):S})},[]),m=d.useCallback(async()=>{try{const p=await F.get("/connection-info");i(p)}catch{i(null)}},[]),P=d.useCallback(async()=>{try{const p=await F.get("/api/dashboard/studio-routing");g(p)}catch{g(null)}},[]),I=d.useCallback(async p=>{const j=await F.patch("/api/dashboard/studio-routing",p);return g(j),await m(),j},[m]),M=d.useCallback(async()=>{try{const p=await F.get("/api/dashboard/connection-log");w(p.entries??[])}catch{w([])}},[]),H=d.useCallback(async()=>{await F.post("/api/dashboard/connection-log/clear"),w([])},[]),C=d.useCallback(async p=>{await F.post("/api/dashboard/kill-agent",{instanceId:p}),await m()},[m]);return d.useEffect(()=>{t!=="disconnected"&&s?(m(),P()):g(null),M()},[t,s,m,M,P]),d.useEffect(()=>{const p=new ce;b.current=p,p.connect();const j=p.on("connection",S=>{const h=S;h.status!=="updated"&&h.clientId&&A(`Plugin ${h.status} — ${h.clientId}`,h.status==="disconnected"?"warn":"info"),m(),P()}),N=p.on("mcp_status",S=>{const h=S,z=h.status==="registered"?"registered":"unregistered";A(`MCP ${z} — ${h.aiClientName}`,h.status==="registered"?"info":"warn"),m(),P()});return()=>{j(),N(),p.disconnect(),b.current=null}},[A,m,P]),{status:s,connectionInfo:l,studioRouting:y,connectionLog:c,level:t,error:n,clearConnectionLog:H,killAgent:C,updateStudioRouting:I}}const Le="_page_14kg9_2",Ae="_card_14kg9_11",Pe="_topologyCard_14kg9_19",Be="_topologyDisconnected_14kg9_26",$e="_topologyHeader_14kg9_30",Me="_topologyIntro_14kg9_38",Ee="_topologyNetwork_14kg9_45",Te="_topologyLinks_14kg9_49",He="_topologyLink_14kg9_49",De="_topologyLink_agent_14kg9_66",Ue="_topologyLink_studio_14kg9_70",Oe="_topologyGrid_14kg9_74",Fe="_topologyColumn_14kg9_83",We="_topologyColumnHeader_14kg9_90",ze="_topologyColumnHeaderSpacer_14kg9_101",Ye="_topologyCount_14kg9_105",Ve="_topologyList_14kg9_120",Ge="_topologyListCentered_14kg9_128",qe="_topologyNode_14kg9_132",Re="_topologyNodeTitle_14kg9_140",Ke="_topologyNodeMeta_14kg9_156",Xe="_topologyNodeSubtle_14kg9_157",Je="_topologyState_14kg9_170",Qe="_topologyEmpty_14kg9_183",Ze="_topologyOverflow_14kg9_198",et="_topologyOverflowButton_14kg9_213",tt="_topologyServerColumn_14kg9_236",ot="_topologyServer_14kg9_236",nt="_topologyServerIcon_14kg9_254",st="_topologyServerBody_14kg9_267",it="_topologyServerTitle_14kg9_276",ct="_topologyServerMeta_14kg9_283",lt="_routingSummaryCompact_14kg9_290",at="_disabled_14kg9_298",rt="_cardHeader_14kg9_304",dt="_cardHint_14kg9_317",gt="_clearButton_14kg9_324",pt="_serverGrid_14kg9_348",ut="_statusRow_14kg9_366",ht="_metaItem_14kg9_373",yt="_table_14kg9_380",mt="_tableWrap_14kg9_400",xt="_routingSummary_14kg9_290",_t="_manageLink_14kg9_416",St="_segment_14kg9_442",jt="_segmentActive_14kg9_443",vt="_targetPrimary_14kg9_477",kt="_monoMuted_14kg9_481",ft="_copyIconButton_14kg9_485",bt="_routingBadge_14kg9_510",Ct="_studioStateBadge_14kg9_524",Nt="_studioState_running_14kg9_539",wt="_studioState_paused_14kg9_545",It="_studioState_edit_14kg9_551",Lt="_studioState_unknown_14kg9_557",At="_toggleBtn_14kg9_564",Pt="_disconnected_14kg9_579",Bt="_disconnectedActions_14kg9_596",$t="_btn_14kg9_603",Mt="_activity_active_14kg9_621",Et="_activity_stale_14kg9_622",Tt="_activity_unknown_14kg9_623",Ht="_killBtn_14kg9_647",Dt="_emptyRow_14kg9_671",o={page:Le,card:Ae,topologyCard:Pe,topologyDisconnected:Be,topologyHeader:$e,topologyIntro:Me,topologyNetwork:Ee,topologyLinks:Te,topologyLink:He,topologyLink_agent:De,topologyLink_studio:Ue,topologyGrid:Oe,topologyColumn:Fe,topologyColumnHeader:We,topologyColumnHeaderSpacer:ze,topologyCount:Ye,topologyList:Ve,topologyListCentered:Ge,topologyNode:qe,topologyNodeTitle:Re,topologyNodeMeta:Ke,topologyNodeSubtle:Xe,topologyState:Je,topologyEmpty:Qe,topologyOverflow:Ze,topologyOverflowButton:et,topologyServerColumn:tt,topologyServer:ot,topologyServerIcon:nt,topologyServerBody:st,topologyServerTitle:it,topologyServerMeta:ct,routingSummaryCompact:lt,disabled:at,cardHeader:rt,cardHint:dt,clearButton:gt,serverGrid:pt,statusRow:ut,metaItem:ht,table:yt,tableWrap:mt,routingSummary:xt,manageLink:_t,segment:St,segmentActive:jt,targetPrimary:vt,monoMuted:kt,copyIconButton:ft,routingBadge:bt,studioStateBadge:Ct,studioState_running:Nt,studioState_paused:wt,studioState_edit:It,studioState_unknown:Lt,toggleBtn:At,disconnected:Pt,disconnectedActions:Bt,btn:$t,activity_active:Mt,activity_stale:Et,activity_unknown:Tt,killBtn:Ht,emptyRow:Dt},G=5;function Ut(t){return t?Date.now()-t<3e4?"active":"stale":"unknown"}function Ot(t,s){return t==="active"?s("connection.topology.active","Active"):t==="stale"?s("connection.topology.stale","Stale"):s("connection.topology.unknown","Unknown")}function Z(t){return t.length>10?t.slice(0,10):t}function ee(t,s){return t.replace("{count}",String(s))}function Ft(t,s,n){const l=t.studioState??"unknown",i={edit:s("connection.targets.studioState.edit","Edit"),running:s("connection.targets.studioState.running","Running"),paused:s("connection.targets.studioState.paused","Paused"),unknown:s("connection.targets.studioState.unknown","Unknown")},y=t.studioStateSource==="thread"?s("connection.targets.studioState.source.thread","WEPPY play command"):t.studioStateSource==="pluginConnection"?s("connection.targets.studioState.source.pluginConnection","Studio Play/Test connection"):t.studioStateSource==="runService"?s("connection.targets.studioState.source.runService","Studio RunService"):s("connection.targets.studioState.source.unknown","Unknown source"),g=t.studioStateUpdatedAt?n(t.studioStateUpdatedAt):s("connection.targets.studioState.updatedUnknown","not reported");return{state:l,label:i[l],tooltip:`${y} · ${g}`}}function Wt(t,s){return t.length!==s.length?!1:t.every((n,l)=>{const i=s[l];return i!==void 0&&n.id===i.id&&n.side===i.side&&Math.abs(n.x1-i.x1)<.5&&Math.abs(n.y1-i.y1)<.5&&Math.abs(n.x2-i.x2)<.5&&Math.abs(n.y2-i.y2)<.5})}function f(t,s,n){return{x:s-t.left,y:n-t.top}}function zt(t,s,n,l){if(s.right<=n.left){const g=f(l,s.right,s.top+s.height/2),c=f(l,n.left,n.top+n.height/2);return{id:t,side:"agent",x1:g.x,y1:g.y,x2:c.x,y2:c.y}}if(s.bottom<=n.top){const g=f(l,s.left+s.width/2,s.bottom),c=f(l,n.left+n.width/2,n.top);return{id:t,side:"agent",x1:g.x,y1:g.y,x2:c.x,y2:c.y}}const i=f(l,s.left+s.width/2,s.top),y=f(l,n.left+n.width/2,n.bottom);return{id:t,side:"agent",x1:i.x,y1:i.y,x2:y.x,y2:y.y}}function Yt(t,s,n,l){if(n.right<=s.left){const g=f(l,s.left,s.top+s.height/2),c=f(l,n.right,n.top+n.height/2);return{id:t,side:"studio",x1:g.x,y1:g.y,x2:c.x,y2:c.y}}if(n.bottom<=s.top){const g=f(l,s.left+s.width/2,s.top),c=f(l,n.left+n.width/2,n.bottom);return{id:t,side:"studio",x1:g.x,y1:g.y,x2:c.x,y2:c.y}}const i=f(l,s.left+s.width/2,s.bottom),y=f(l,n.left+n.width/2,n.top);return{id:t,side:"studio",x1:i.x,y1:i.y,x2:y.x,y2:y.y}}function Vt({agents:t,isDisconnected:s,pinnedTargetClientId:n,priorityTarget:l,status:i,studioRoutingMode:y,studioTargets:g,t:c,timeAgo:w,onCopySelector:b,onManageRouting:A}){const[m,P]=d.useState(!1),[I,M]=d.useState(!1),[H,C]=d.useState([]),p=d.useRef(null),j=d.useRef(null),N=d.useRef(new Map),S=d.useRef(new Map),h=y==="pinned"?c("connection.routing.pinned","Manual: Pinned Studio"):c("connection.routing.recentPriority","Automatic: Recent priority"),z=s?"offline":"online",k=d.useMemo(()=>m?t:t.slice(0,G),[t,m]),D=Math.max(0,t.length-k.length),v=d.useMemo(()=>I?g:g.slice(0,G),[g,I]),E=Math.max(0,g.length-v.length),R=[o.topologyList,k.length<=1?o.topologyListCentered:""].filter(Boolean).join(" "),K=[o.topologyList,v.length<=1?o.topologyListCentered:""].filter(Boolean).join(" "),U=d.useCallback(a=>x=>{if(x){N.current.set(a,x);return}N.current.delete(a)},[]),r=d.useCallback(a=>x=>{if(x){S.current.set(a,x);return}S.current.delete(a)},[]),L=d.useCallback(()=>{const a=p.current,x=j.current;if(!a||!x){C([]);return}const _=a.getBoundingClientRect(),B=x.getBoundingClientRect(),O=[];k.forEach($=>{const Y=N.current.get($.instanceId);Y&&O.push(zt(`agent-${$.instanceId}`,Y.getBoundingClientRect(),B,_))}),v.forEach($=>{const Y=S.current.get($.clientId);Y&&O.push(Yt(`studio-${$.clientId}`,Y.getBoundingClientRect(),B,_))}),C($=>Wt($,O)?$:O)},[k,v]);return d.useLayoutEffect(()=>{L();const a=[p.current,j.current,...k.map(_=>N.current.get(_.instanceId)),...v.map(_=>S.current.get(_.clientId))].filter(_=>_!=null);if(window.addEventListener("resize",L),typeof ResizeObserver>"u")return()=>{window.removeEventListener("resize",L)};const x=new ResizeObserver(L);return a.forEach(_=>x.observe(_)),()=>{window.removeEventListener("resize",L),x.disconnect()}},[L,k,v]),e.jsxs("section",{className:`${o.topologyCard} ${s?o.topologyDisconnected:""}`,"aria-label":c("connection.topology.ariaLabel","Connection topology"),children:[e.jsxs("div",{className:o.topologyHeader,children:[e.jsxs("div",{children:[e.jsx("div",{className:o.cardHeader,children:c("connection.topology.title","Connection topology")}),e.jsx("p",{className:o.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(le,{to:"/controls?section=studio-routing",className:o.manageLink,onClick:A,children:c("connection.routing.manage","Manage routing")})]}),e.jsxs("div",{className:o.topologyNetwork,ref:p,children:[e.jsx("svg",{"aria-hidden":"true",className:o.topologyLinks,"data-testid":"topology-connection-lines",focusable:"false",children:H.map(a=>e.jsx("line",{className:`${o.topologyLink} ${o[`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:o.topologyGrid,children:[e.jsxs("div",{className:o.topologyColumn,children:[e.jsxs("div",{className:o.topologyColumnHeader,children:[e.jsx(ye,{size:15,"aria-hidden":"true"}),e.jsx("span",{children:c("connection.agents.title","AI Agents")}),e.jsx("span",{className:o.topologyCount,children:t.length})]}),e.jsxs("div",{className:R,children:[t.length>0?k.map(a=>{const x=Ut(a.lastSeen),_=a.aiClientName??Z(a.instanceId),B=a.lastSeen??a.lastCommandAt??a.connectedAt,O=a.mcpVersion?`${c("connection.topology.adapterRole","MCP Adapter")} v${a.mcpVersion}`:c("connection.topology.adapterRole","MCP Adapter");return e.jsxs("div",{className:o.topologyNode,ref:U(a.instanceId),children:[e.jsxs("div",{className:o.topologyNodeTitle,children:[e.jsx("span",{className:o[`activity_${x}`]}),e.jsx("strong",{children:_}),e.jsx("span",{className:o.topologyState,children:Ot(x,c)})]}),e.jsxs("div",{className:o.topologyNodeMeta,children:[e.jsx("span",{children:O})," ·"," ",c("connection.server.session","Session")," ",Z(a.instanceId)," ·"," ",B?`${c("connection.topology.lastActivity","Last activity")} ${w(B)}`:c("connection.topology.noActivity","No recent activity")]})]},a.instanceId)}):e.jsx("div",{className:o.topologyEmpty,children:c("connection.agents.none","No agents connected")}),t.length>G?e.jsxs("div",{className:o.topologyOverflow,children:[D>0?e.jsx("span",{children:ee(c("connection.topology.moreAgents","+{count} more agents"),D)}):e.jsx("span",{children:c("connection.topology.allAgentsVisible","All agents visible")}),e.jsx("button",{type:"button",className:o.topologyOverflowButton,"aria-label":m?c("connection.topology.showLessAgents","Show less AI agents"):c("connection.topology.showAllAgents","Show all AI agents"),onClick:()=>P(a=>!a),children:m?c("connection.topology.showLess","Show less"):c("connection.topology.showAll","Show all")})]}):null]})]}),e.jsxs("div",{className:o.topologyServerColumn,children:[e.jsx("div",{className:o.topologyColumnHeaderSpacer,"aria-hidden":"true"}),e.jsxs("div",{className:`${o.topologyNode} ${o.topologyServer}`,ref:j,children:[e.jsx("div",{className:o.topologyServerIcon,children:e.jsx(xe,{size:18,"aria-hidden":"true"})}),e.jsxs("div",{className:o.topologyServerBody,children:[e.jsx("div",{className:o.topologyServerTitle,children:c("connection.topology.serverTitle","WEPPY Bridge")}),e.jsx(ne,{status:z}),e.jsxs("div",{className:o.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:o.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")} ${se(i.uptime)}`}):null]}):null,e.jsx("div",{className:o.routingSummaryCompact,children:e.jsx("span",{className:o.routingBadge,children:h})})]})]})]}),e.jsxs("div",{className:o.topologyColumn,children:[e.jsxs("div",{className:o.topologyColumnHeader,children:[e.jsx(ae,{size:15,"aria-hidden":"true"}),e.jsx("span",{children:c("connection.targets.title","Studio Targets")}),e.jsx("span",{className:o.topologyCount,children:g.length})]}),e.jsxs("div",{className:K,children:[g.length>0?v.map(a=>{const x=y==="pinned"&&n===a.clientId,_=y==="recentPriority"&&(l==null?void 0:l.clientId)===a.clientId,B=Ft(a,c,w);return e.jsxs("div",{className:o.topologyNode,ref:r(a.clientId),children:[e.jsxs("div",{className:o.topologyNodeTitle,children:[e.jsx("span",{className:o.targetPrimary,children:a.targetAlias}),e.jsx(V,{text:c("connection.targets.copyTargetAlias","Copy Studio ID"),children:e.jsx("button",{type:"button",className:o.copyIconButton,"aria-label":c("connection.targets.copyTargetAlias","Copy Studio ID"),onClick:()=>b(a.targetAlias,"target_alias"),children:e.jsx(q,{size:13,"aria-hidden":"true"})})}),x?e.jsx("span",{className:o.routingBadge,children:c("connection.routing.pinnedBadge","Pinned")}):_?e.jsx("span",{className:o.routingBadge,children:c("connection.routing.priorityBadge","Priority")}):null,e.jsx(V,{text:B.tooltip,children:e.jsx("span",{className:`${o.studioStateBadge} ${o[`studioState_${B.state}`]}`,children:B.label})})]}),e.jsxs("div",{className:o.topologyNodeMeta,children:[e.jsx("span",{children:a.placeName??c("connection.topology.placeUnknown","Place unknown")}),a.placeId!==void 0?` · ${a.placeId}`:""]}),e.jsxs("div",{className:o.topologyNodeSubtle,children:[a.connectionState," · ",c("connection.targets.lastSeen","Last Seen")," ",w(a.lastSeen)]})]},a.clientId)}):e.jsx("div",{className:o.topologyEmpty,children:c("connection.targets.none","No Studio targets connected. Open Roblox Studio and connect WEPPY Plugin.")}),g.length>G?e.jsxs("div",{className:o.topologyOverflow,children:[E>0?e.jsx("span",{children:ee(c("connection.topology.moreStudios","+{count} more studios"),E)}):e.jsx("span",{children:c("connection.topology.allStudiosVisible","All studios visible")}),e.jsx("button",{type:"button",className:o.topologyOverflowButton,"aria-label":I?c("connection.topology.showLessStudios","Show less Studio targets"):c("connection.topology.showAllStudios","Show all Studio targets"),onClick:()=>M(a=>!a),children:I?c("connection.topology.showLess","Show less"):c("connection.topology.showAll","Show all")})]}):null]})]})]})]})]})}function T(t,s){const n=Math.max(0,Math.floor((Date.now()-t)/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 Gt(t){return t?Date.now()-t<3e4?"active":"stale":"unknown"}function qt(t,s){const n=t.studioState??"unknown",l={edit:s("connection.targets.studioState.edit","Edit"),running:s("connection.targets.studioState.running","Running"),paused:s("connection.targets.studioState.paused","Paused"),unknown:s("connection.targets.studioState.unknown","Unknown")},i=t.studioStateSource==="thread"?s("connection.targets.studioState.source.thread","WEPPY play command"):t.studioStateSource==="pluginConnection"?s("connection.targets.studioState.source.pluginConnection","Studio Play/Test connection"):t.studioStateSource==="runService"?s("connection.targets.studioState.source.runService","Studio RunService"):s("connection.targets.studioState.source.unknown","Unknown source"),y=t.studioStateUpdatedAt?T(t.studioStateUpdatedAt,s):s("connection.targets.studioState.updatedUnknown","not reported"),g=t.playtestMode&&t.playtestMode!=="unknown"?` · ${t.playtestMode}`:"";return{state:n,label:`${l[n]}${g}`,tooltip:`${i} · ${y}`}}function no(){const{t}=oe(),{trackEvent:s}=re(),{status:n,connectionInfo:l,studioRouting:i,connectionLog:y,level:g,clearConnectionLog:c,killAgent:w}=Ie(),{show:b}=de(),[A,m]=d.useState(!0),[P,I]=d.useState(!1),[M,H]=d.useState(!1),[C,p]=d.useState(null),[j,N]=d.useState(!1),S=ue(n==null?void 0:n.uptime),h=g==="disconnected",z=h?"offline":"online",k=(i==null?void 0:i.studioRoutingMode)??(n==null?void 0:n.studioRoutingMode)??"recentPriority",D=(i==null?void 0:i.pinnedTargetClientId)??(n==null?void 0:n.pinnedTargetClientId)??null,v=ge((i==null?void 0:i.targets)??(n==null?void 0:n.pluginClients)??[],k,D),E=(i==null?void 0:i.priorityTarget)??v[0],R=async()=>{if(C){N(!0);try{await w(C.instanceId),b(t("connection.agents.killed","Agent killed"),"success"),p(null)}catch{b(t("connection.agents.killFailed","Failed to kill agent"),"error")}finally{N(!1)}}},K=async()=>{H(!0);try{await c(),b(t("toast.clearSuccess","Cleared successfully"),"success"),I(!1)}catch{b(t("toast.clearFailed","Failed to clear data"),"error")}finally{H(!1)}},U=async(r,L)=>{try{await navigator.clipboard.writeText(r),b(t("connection.targets.copied","Copied value"),"success"),s("dashboard_click_event",{click_target:`connection_copy_${L}`,page:"connection"})}catch{b(t("connection.targets.copyFailed","Failed to copy value"),"error")}};return e.jsxs("div",{className:o.page,children:[e.jsx(pe,{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:g}}),e.jsx(Vt,{agents:(l==null?void 0:l.mcpInstances)??[],isDisconnected:h,pinnedTargetClientId:D,priorityTarget:E,status:n??null,studioRoutingMode:k,studioTargets:v,t,timeAgo:r=>T(r,t),onCopySelector:U,onManageRouting:()=>s("dashboard_click_event",{click_target:"connection_manage_routing",page:"connection"})}),e.jsxs("div",{className:o.card,children:[e.jsx("div",{className:o.cardHeader,children:t("connection.server.title","Bridge Status")}),h?e.jsxs("div",{className:o.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:o.disconnectedActions,children:[e.jsx("button",{className:o.btn,onClick:()=>window.location.reload(),children:t("connection.reconnect","Reconnect")}),e.jsx("button",{className:o.btn,onClick:()=>{window.location.hash="#/settings"},children:t("connection.checkSettings","Check Settings")})]})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:o.statusRow,children:e.jsx(ne,{status:z})}),e.jsxs("dl",{className:o.serverGrid,children:[(n==null?void 0:n.version)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(u,{label:t("connection.server.version","Version"),tooltip:t("connection.server.version.tooltip","WEPPY Bridge runtime version")})}),e.jsx("dd",{children:e.jsx(X,{text:t("connection.server.version.tooltip","WEPPY Bridge runtime version"),children:`v${n.version}`})})]}),(n==null?void 0:n.pid)!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(u,{label:t("connection.server.pid","PID"),tooltip:t("connection.server.pid.tooltip","Operating system process identifier")})}),e.jsx("dd",{children:n.pid})]}),(n==null?void 0:n.uptime)!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(u,{label:t("connection.server.uptime","Uptime"),tooltip:t("connection.server.uptime.tooltip","Time elapsed since the WEPPY Bridge started")})}),e.jsx("dd",{children:se(S??n.uptime)})]}),(n==null?void 0:n.sessionId)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(u,{label:t("connection.server.session","Session"),tooltip:t("connection.server.session.tooltip","Current WEPPY Bridge session identifier")})}),e.jsx("dd",{children:n.sessionId.slice(0,8)})]}),(l==null?void 0:l.serverExecutable)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(u,{label:t("connection.server.exec","Exec"),tooltip:t("connection.server.exec.tooltip","Executable path used to launch the WEPPY Bridge")})}),e.jsx("dd",{children:l.serverExecutable})]})]})]})]}),e.jsxs("div",{className:`${o.card} ${h?o.disabled:""}`,children:[e.jsxs("div",{className:o.cardHeader,children:[e.jsxs("span",{children:[t("connection.agents.title","AI Agents")," ","(",(l==null?void 0:l.mcpInstanceCount)??0,")"]}),e.jsx("button",{className:o.toggleBtn,onClick:()=>m(r=>!r),"aria-label":A?t("common.collapse","Collapse"):t("common.expand","Expand"),children:A?"▾":"▸"})]}),A&&e.jsxs("table",{className:o.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(u,{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(u,{label:t("connection.server.pid","PID"),tooltip:t("connection.server.pid.tooltip","Operating system process identifier")})}),e.jsx("th",{children:e.jsx(u,{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(u,{label:t("connection.agents.lastSeen","Last Seen"),tooltip:t("connection.agents.lastSeen.tooltip","Most recent heartbeat or activity from this agent")})}),e.jsx("th",{children:e.jsx(u,{label:t("connection.agents.lastCommand","Last Command"),tooltip:t("connection.agents.lastCommand.tooltip","Most recent tool call executed by this agent")})}),e.jsx("th",{})]})}),e.jsx("tbody",{children:l!=null&&l.mcpInstances&&l.mcpInstances.length>0?l.mcpInstances.map(r=>e.jsxs("tr",{children:[e.jsxs("td",{children:[e.jsx("span",{className:o[`activity_${Gt(r.lastSeen)}`]}),r.aiClientName??t("connection.agents.unknown","Unknown")]}),e.jsx("td",{children:r.mcpVersion??"-"}),e.jsx("td",{children:r.pid}),e.jsx("td",{children:r.projectRoot??r.cwd??t("connection.agents.projectRoot.unresolved","Unresolved")}),e.jsx("td",{children:T(r.connectedAt,t)}),e.jsx("td",{children:r.lastSeen?T(r.lastSeen,t):"-"}),e.jsx("td",{children:r.lastCommandAt?T(r.lastCommandAt,t):"-"}),e.jsx("td",{children:!r.isServer&&e.jsx("button",{className:o.killBtn,onClick:()=>{s("dashboard_click_event",{click_target:"connection_kill_agent",page:"connection"}),p({instanceId:r.instanceId,name:r.aiClientName??r.instanceId.slice(0,8)})},children:t("connection.agents.kill","Kill")})})]},r.instanceId)):e.jsx("tr",{children:e.jsx("td",{colSpan:8,className:o.emptyRow,children:t("connection.agents.none","No agents connected")})})})]})]}),e.jsxs("div",{className:`${o.card} ${h?o.disabled:""}`,children:[e.jsxs("div",{className:o.cardHeader,children:[t("connection.targets.title","Studio Targets")," ","(",v.length,")"]}),e.jsx("p",{className:o.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:o.tableWrap,children:e.jsxs("table",{className:o.table,children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:e.jsx(u,{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(u,{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(u,{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(u,{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(u,{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(u,{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(u,{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(u,{label:t("connection.targets.version","Version"),tooltip:t("connection.targets.version.tooltip","Installed plugin version reported by Studio")})}),e.jsx("th",{children:e.jsx(u,{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(u,{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:v.length>0?v.map(r=>{const L=r.clientId.slice(0,10),a=qt(r,t);return e.jsxs("tr",{children:[e.jsxs("td",{children:[e.jsx("span",{className:o.monoMuted,title:r.clientId,children:r.targetAlias}),e.jsx(V,{text:t("connection.targets.copyTargetAlias","Copy Studio ID"),children:e.jsx("button",{type:"button",className:o.copyIconButton,"aria-label":t("connection.targets.copyTargetAlias","Copy Studio ID"),onClick:()=>U(r.targetAlias,"target_alias"),children:e.jsx(q,{size:13,"aria-hidden":"true"})})})]}),e.jsx("td",{children:e.jsx("span",{className:o.targetPrimary,children:r.placeName??"-"})}),e.jsxs("td",{children:[r.placeId??"-",r.placeId!==void 0?e.jsx(V,{text:t("connection.targets.copyPlaceId","Copy Place ID"),children:e.jsx("button",{type:"button",className:o.copyIconButton,"aria-label":t("connection.targets.copyPlaceId","Copy Place ID"),onClick:()=>U(String(r.placeId),"place_id"),children:e.jsx(q,{size:13,"aria-hidden":"true"})})}):null]}),e.jsxs("td",{children:[e.jsx("span",{className:o.monoMuted,title:r.clientId,children:L}),e.jsx(V,{text:t("connection.targets.copyClientId","Copy Connection ID"),children:e.jsx("button",{type:"button",className:o.copyIconButton,"aria-label":t("connection.targets.copyClientId","Copy Connection ID"),onClick:()=>U(r.clientId,"client_id"),children:e.jsx(q,{size:13,"aria-hidden":"true"})})})]}),e.jsx("td",{children:e.jsx(X,{text:a.tooltip,children:e.jsx("span",{className:`${o.studioStateBadge} ${o[`studioState_${a.state}`]}`,children:a.label})})}),e.jsx("td",{children:r.connectionState}),e.jsx("td",{children:r.lastRoutedAt?T(r.lastRoutedAt,t):"-"}),e.jsx("td",{children:T(r.lastSeen,t)}),e.jsx("td",{children:r.pluginVersion??"-"}),e.jsx("td",{children:k==="pinned"&&D===r.clientId?e.jsx("span",{className:o.routingBadge,children:t("connection.routing.pinnedBadge","Pinned")}):k==="recentPriority"&&(E==null?void 0:E.clientId)===r.clientId?e.jsx("span",{className:o.routingBadge,children:t("connection.routing.priorityBadge","Priority")}):e.jsx("span",{className:o.monoMuted,children:"-"})}),e.jsx("td",{children:r.inFlightRequestId?r.inFlightRequestId.slice(0,8):"-"})]},r.clientId)}):e.jsx("tr",{children:e.jsx("td",{colSpan:11,className:o.emptyRow,children:t("connection.targets.none","No Studio targets connected. Open Roblox Studio and connect WEPPY Plugin.")})})})]})})]}),e.jsxs("div",{className:`${o.card} ${h?o.disabled:""}`,children:[e.jsxs("div",{className:o.cardHeader,children:[e.jsx("span",{children:t("connection.log.title","Connection Log")}),e.jsx("button",{className:o.clearButton,onClick:()=>{s("dashboard_click_event",{click_target:"connection_clear_log",page:"connection"}),I(!0)},children:t("common.clear","Clear")})]}),e.jsx(Ne,{entries:y})]}),e.jsx(J,{open:P,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:M,onCancel:()=>!M&&I(!1),onConfirm:K}),e.jsx(J,{open:!!C,title:t("connection.agents.kill.title","Kill agent?"),message:`"${C==null?void 0:C.name}" 프로세스를 강제 종료합니다. 해당 에이전트의 진행 중인 작업이 중단됩니다.`,cancelLabel:t("common.cancel","Cancel"),confirmLabel:t("connection.agents.kill","Kill"),loading:j,onCancel:()=>!j&&p(null),onConfirm:R})]})}export{no as Component};
@@ -0,0 +1 @@
1
+ import{r as f,t as E,j as m}from"./index-Ygt1Wh6v.js";const v="_backdrop_1sgib_1",x="_dialog_1sgib_19",b={backdrop:v,dialog:x},h=["a[href]","button:not([disabled])","input:not([disabled])","select:not([disabled])","textarea:not([disabled])",'[contenteditable="true"]','[tabindex]:not([tabindex="-1"])'].join(", ");function k(o){return Array.from(o.querySelectorAll(h))}function D(o){const a=document.activeElement;if(!(a instanceof HTMLElement))return!1;const n=a.closest('[role="dialog"][aria-modal="true"]');return n!==null&&n!==o}function _({open:o,ariaLabel:a,onClose:n,returnFocusTo:r=null,children:g,testId:y}){const l=f.useRef(null);return f.useEffect(()=>{if(!o)return;const e=l.current;if(!e)return;const p=document.body.style.overflow;document.body.style.overflow="hidden",e.focus();const c=t=>{if(D(e))return;if(t.key==="Escape"){t.preventDefault(),n();return}if(t.key!=="Tab")return;const i=k(e);if(i.length===0){t.preventDefault(),e.focus();return}const d=i[0],u=i[i.length-1],s=document.activeElement;t.shiftKey&&(s===d||!e.contains(s))?(t.preventDefault(),u.focus()):!t.shiftKey&&(s===u||!e.contains(s))&&(t.preventDefault(),d.focus())};return document.addEventListener("keydown",c),()=>{document.removeEventListener("keydown",c),document.body.style.overflow=p,r&&document.contains(r)&&r.focus()}},[n,o,r]),o?E.createPortal(m.jsx("div",{className:b.backdrop,"data-testid":y,role:"presentation",onClick:e=>{e.target===e.currentTarget&&n()},children:m.jsx("section",{ref:l,className:b.dialog,role:"dialog","aria-modal":"true","aria-label":a,tabIndex:-1,children:g})}),document.body):null}export{_ as C};
@@ -0,0 +1 @@
1
+ ._backdrop_1sgib_1{position:fixed;top:calc(var(--header-height) + 16px);right:24px;bottom:24px;left:calc(var(--sidebar-width) + 24px);z-index:900;display:flex;align-items:stretch;justify-content:center;min-width:0;padding:clamp(12px,2vw,24px);overflow:hidden;box-sizing:border-box;background:#03071294;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}._dialog_1sgib_19{display:flex;flex:1;flex-direction:column;width:100%;height:100%;min-width:0;min-height:0;overflow:hidden;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg-card);box-shadow:0 24px 60px #0000006b}._dialog_1sgib_19>*{min-width:0;min-height:0;max-height:100%}@media(max-width:1120px){._backdrop_1sgib_1{right:16px;bottom:16px;left:calc(var(--sidebar-width) + 16px);padding:12px}}@media(max-width:768px){._backdrop_1sgib_1{top:calc(var(--header-height) + 10px);right:10px;bottom:10px;left:calc(var(--sidebar-collapsed) + 10px);padding:8px}}
@@ -1,6 +1,6 @@
1
- import{i as K,u as P,j as e,f as q,l as z,d as k,r as l,v as Z,w as J,x as ee,a as U,s as te,y as ne,k as D,N as oe}from"./index-CACN5u4J.js";import{D as Q,P as ae}from"./PageHeader-CTOJDcG8.js";import{I as T}from"./InfoLabel-Cf_fu0ZE.js";import{s as j}from"./ConfirmModal.module-DJksQHBd.js";import{T as F}from"./TooltipText-55u9HaGy.js";import{s as t,u as ie}from"./useSettings-COna4-LR.js";import{C as B}from"./copy-szgBQciT.js";import"./UiPrimitive-BUpeGXNh.js";/**
1
+ import{f as K,u as P,j as e,d as q,i as z,c as k,r as l,v as Z,w as J,x as ee,b as U,s as te,y as ne,h as D,N as oe}from"./index-Ygt1Wh6v.js";import{D as Q,P as ae}from"./PageHeader-Xrn6BpcL.js";import{I as T}from"./InfoLabel-D6WxKFnG.js";import{s as j}from"./ConfirmModal.module-DJksQHBd.js";import{T as F}from"./TooltipText-B1An7dUI.js";import{s as t,u as ie}from"./useSettings-BrnGUYZY.js";import{C as B}from"./copy-B03ftJiE.js";/**
2
2
  * @license lucide-react v1.8.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
5
5
  * See the LICENSE file in the root directory of this source tree.
6
- */const se=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],_=K("check",se);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 le(o){const n=/^[A-Z]:\\/i.test(o)||o.includes("\\")?"\\":"/";return`${o.replace(/[\\/]+$/,"")}${n}weppy-project-sync`}function ce({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?le(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 re(){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 Z();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 ee();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(ce,{open:y!==null,step:y??"initial",selectedProjectRoot:b,studioConnected:o==="studioConnected",loading:S||f,errorMessage:L,onClose:R,onPick:I,onApply:A})]})}function de(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 ue(){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=te((c==null?void 0:c.targets)??(o==null?void 0:o.pluginClients)??[],u,f),L=(c==null?void 0:c.priorityTarget)??ne(v,u,f),C=de(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(_,{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(_,{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(_,{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(B,{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(B,{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(B,{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 pe({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 he({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 Ne(){const{t:o}=P(),{search:s}=k(),{settings:n,updateHotSetting:d,saving:p,loading:h}=ie();return l.useMemo(()=>new URLSearchParams(s).get("section"),[s])==="license"?e.jsx(oe,{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(ae,{title:o("page.controls.title","Controls"),description:o("page.controls.description","Manage project root, Studio routing, and MCP live settings."),helpTopicId:"controls"}),e.jsx(re,{}),e.jsx(ue,{}),e.jsx(he,{enabled:(n==null?void 0:n.hot.SCRIPT_WRITE_VALIDATION_ENABLED)??!1,saving:p,onChange:c=>d("SCRIPT_WRITE_VALIDATION_ENABLED",c)}),e.jsx(pe,{settings:n,updateHotSetting:d})]})}export{Ne as Component};
6
+ */const se=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],_=K("check",se);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 le(o){const n=/^[A-Z]:\\/i.test(o)||o.includes("\\")?"\\":"/";return`${o.replace(/[\\/]+$/,"")}${n}weppy-project-sync`}function ce({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?le(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 re(){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 Z();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 ee();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(ce,{open:y!==null,step:y??"initial",selectedProjectRoot:b,studioConnected:o==="studioConnected",loading:S||f,errorMessage:L,onClose:R,onPick:I,onApply:A})]})}function de(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 ue(){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=te((c==null?void 0:c.targets)??(o==null?void 0:o.pluginClients)??[],u,f),L=(c==null?void 0:c.priorityTarget)??ne(v,u,f),C=de(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(_,{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(_,{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(_,{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(B,{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(B,{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(B,{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 pe({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 he({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 be(){const{t:o}=P(),{search:s}=k(),{settings:n,updateHotSetting:d,saving:p,loading:h}=ie();return l.useMemo(()=>new URLSearchParams(s).get("section"),[s])==="license"?e.jsx(oe,{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(ae,{title:o("page.controls.title","Controls"),description:o("page.controls.description","Manage project root, Studio routing, and MCP live settings."),helpTopicId:"controls"}),e.jsx(re,{}),e.jsx(ue,{}),e.jsx(he,{enabled:(n==null?void 0:n.hot.SCRIPT_WRITE_VALIDATION_ENABLED)??!1,saving:p,onChange:c=>d("SCRIPT_WRITE_VALIDATION_ENABLED",c)}),e.jsx(pe,{settings:n,updateHotSetting:d})]})}export{be as Component};
@@ -0,0 +1 @@
1
+ import{u as h,r as f,j as a,g as _}from"./index-Ygt1Wh6v.js";import{B as x}from"./PageHeader-Xrn6BpcL.js";const j="_scope_1kz7c_1",m="_main_1kz7c_13",k="_label_1kz7c_20",I="_selectorLabel_1kz7c_28",w="_placeSelect_1kz7c_35",z="_name_1kz7c_48",A="_id_1kz7c_59",L="_scopeBadge_1kz7c_66",y="_copy_1kz7c_70",E="_note_1kz7c_82",n={scope:j,main:m,label:k,selectorLabel:I,placeSelect:w,name:z,id:A,scopeBadge:L,copy:y,note:E};function d(e,l){return l===null?null:e.places.find(c=>c.placeId===l)??null}function S(e){var l;return e.lastActivePlaceId!==null?e.lastActivePlaceId:((l=e.places[0])==null?void 0:l.placeId)??null}function B(e){return e.pluginConnected&&e.activePlaceId!==null?e.activePlaceId:S(e)}function U(e,l){if(e.pluginConnected&&e.activePlaceId!==null){const o=d(e,e.activePlaceId);return{label:l("placeScope.current.label","Current Place"),placeId:e.activePlaceId,placeName:e.activePlaceName??(o==null?void 0:o.placeName)??l("placeScope.unknownPlace","Unknown place"),badge:l("placeScope.live","Live"),live:!0,note:null}}const c=S(e),s=d(e,c);if(c!==null){const o=c===e.lastActivePlaceId?e.lastActivePlaceName:null;return{label:l("placeScope.lastActive.label","Last Active Place"),placeId:c,placeName:o??(s==null?void 0:s.placeName)??l("placeScope.unknownPlace","Unknown place"),badge:l("placeScope.pluginRequired","Plugin required"),live:!1,note:l("placeScope.pluginRequired.note","Connect WEPPY Plugin to confirm the live active place.")}}return{label:l("placeScope.noPlace.label","Place scope"),placeId:null,placeName:l("placeScope.noPlace.value","No place data available yet"),badge:l("placeScope.noPlace.badge","No place"),live:!1,note:l("placeScope.noPlace.note","Connect WEPPY Plugin and sync a place to create place-scoped data.")}}function q(e,l,c){const s=typeof l=="number"?d(e,l):null,o=B(e),t=(s==null?void 0:s.placeId)??o,r=d(e,t);if(t===null)return{label:c("placeScope.noPlace.label","Place scope"),placeId:null,placeName:c("placeScope.noPlace.value","No place data available yet"),badge:c("placeScope.noPlace.badge","No place"),live:!1,note:c("placeScope.noPlace.note","Connect WEPPY Plugin and sync a place to create place-scoped data.")};const u=e.pluginConnected&&e.activePlaceId===t,b=t===e.lastActivePlaceId?e.lastActivePlaceName:null;return{label:u?c("placeScope.current.label","Current Place"):c("placeScope.selected.label","Selected Place"),placeId:t,placeName:(r==null?void 0:r.placeName)??b??c("placeScope.unknownPlace","Unknown place"),badge:u?c("placeScope.live","Live"):c("placeScope.stored","Stored"),live:u,note:u?null:c("placeScope.selected.note","Showing stored data only. Studio routing is unchanged.")}}function F(e,l){switch(e){case"sync":return l("placeScope.surface.sync","Sync status and logs use this place.");case"changelog":return l("placeScope.surface.changelog","Changelog sessions use this place.");case"playtest":return l("placeScope.surface.playtest","Playtest reports use this place.");case"uiStudio":return l("placeScope.surface.uiStudio","UI captures and change history use this place.");case"tools":return l("placeScope.surface.tools","Tool history and statistics use this place.")}}function W({surface:e,selectable:l=!1,selectedPlaceId:c=null,onSelectedPlaceIdChange:s}){const{t:o}=h(),[t,r]=f.useState(null),[u,b]=f.useState(!0);if(f.useEffect(()=>{let i=!1;async function v(){try{const g=await _();i||r(g)}catch{i||r(null)}finally{i||b(!1)}}return v(),()=>{i=!0}},[]),f.useEffect(()=>{!l||!t||typeof c!="number"||d(t,c)||s==null||s(null)},[s,l,c,t]),u)return a.jsx("div",{className:n.scope,"aria-live":"polite",children:a.jsx("span",{className:n.label,children:o("placeScope.loading","Loading place scope...")})});if(!t)return a.jsx("div",{className:n.scope,"aria-live":"polite",children:a.jsx("span",{className:n.label,children:o("placeScope.unavailable","Place scope unavailable")})});const p=l?q(t,c,o):U(t,o),N=typeof p.placeId=="number"?String(p.placeId):"",P=l&&t.places.length>0;return a.jsxs("div",{className:n.scope,"aria-live":"polite",children:[a.jsxs("div",{className:n.main,children:[P?a.jsxs(a.Fragment,{children:[a.jsxs("label",{className:n.selectorLabel,children:[a.jsx("span",{className:n.label,children:o("placeScope.selector.label","Place data")}),a.jsx("select",{className:n.placeSelect,value:N,onChange:i=>{const v=Number.parseInt(i.currentTarget.value,10);s==null||s(Number.isInteger(v)?v:null)},children:t.places.map(i=>a.jsxs("option",{value:i.placeId,children:[i.placeName," (",i.placeId,")"]},i.placeId))})]}),a.jsx("span",{className:n.label,children:p.label}),a.jsx("span",{className:n.name,children:p.placeName})]}):a.jsxs(a.Fragment,{children:[a.jsx("span",{className:n.label,children:p.label}),a.jsx("span",{className:n.name,children:p.placeName})]}),p.placeId!==null?a.jsx("span",{className:n.id,children:p.placeId}):null,a.jsx(x,{variant:p.live?"success":"warning",shape:"pill",className:n.scopeBadge,children:p.badge})]}),a.jsxs("div",{className:n.copy,children:[a.jsx("span",{children:F(e,o)}),p.note?a.jsx("span",{className:n.note,children:p.note}):null]})]})}export{W as C};
@@ -1,4 +1,4 @@
1
- import{u as _,r as x,j as e}from"./index-CACN5u4J.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(`
1
+ import{u as _,r as x,j as e}from"./index-Ygt1Wh6v.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(`
@@ -1 +1 @@
1
- import{j as r,k as e}from"./index-CACN5u4J.js";function s({label:t,tooltip:o}){return r.jsx(e,{text:o,children:t})}export{s as I};
1
+ import{j as r,h as e}from"./index-Ygt1Wh6v.js";function s({label:t,tooltip:o}){return r.jsx(e,{text:o,children:t})}export{s as I};
@@ -0,0 +1 @@
1
+ import{j as t,u as R,r as v,d as L,e as F,b as M,D as V}from"./index-Ygt1Wh6v.js";import{I as A}from"./InfoLabel-D6WxKFnG.js";import{P as U}from"./PageHeader-Xrn6BpcL.js";import{S as z}from"./StatusBadge-Ddzg1cSk.js";import{T as O}from"./TooltipText-B1An7dUI.js";import{G as X}from"./GameChangeDetail-CCQ8h1ft.js";import{u as q,f as J}from"./useLiveUptime-CnfGQ_vS.js";const K="_page_1xgxh_2",Q="_card_1xgxh_10",W="_cardHeader_1xgxh_17",Y="_disconnectCard_1xgxh_28",Z="_disconnectIcon_1xgxh_36",ee="_disconnectTitle_1xgxh_41",te="_disconnectMessage_1xgxh_48",se="_reconnectGuide_1xgxh_55",ne="_guideStep_1xgxh_64",ie="_stepNumber_1xgxh_72",ce="_reconnectIndicator_1xgxh_88",re="_reconnectDot_1xgxh_98",ae="_pulse_1xgxh_1",oe="_disconnectActions_1xgxh_112",le="_btn_1xgxh_118",de="_btnSecondary_1xgxh_134",me="_metricRow_1xgxh_152",ge="_metricGrid_1xgxh_158",he="_metricCard_1xgxh_164",xe="_metric_ok_1xgxh_174",ue="_metric_warn_1xgxh_179",ve="_metric_error_1xgxh_184",_e="_metricHeader_1xgxh_189",pe="_metricIcon_1xgxh_200",fe="_metricTitle_1xgxh_204",Ce="_metricValue_1xgxh_208",je="_metricSubtitle_1xgxh_215",we="_guideCard_1xgxh_225",Ne="_guideTitle_1xgxh_232",ye="_checklist_1xgxh_239",Te="_feedEmpty_1xgxh_263",Se="_feedList_1xgxh_270",Ie="_feedItem_1xgxh_278",be="_feedTime_1xgxh_291",ke="_feedIcon_1xgxh_298",Me="_feedSummary_1xgxh_304",De="_feedText_1xgxh_313",Be="_feedContext_1xgxh_321",He="_feedItemClickable_1xgxh_330",Ee="_feedChevron_1xgxh_338",Pe="_feedDetail_1xgxh_347",$e="_feedDetailPre_1xgxh_356",Re="_feedDetailText_1xgxh_365",Ge="_changelogSummary_1xgxh_372",Le="_changeTag_1xgxh_381",Fe="_tierBar_1xgxh_393",Ve="_tierBarTrack_1xgxh_399",Ae="_tierBarFillBasic_1xgxh_407",Ue="_tierBarFillPro_1xgxh_412",ze="_tierLabels_1xgxh_417",s={page:K,card:Q,cardHeader:W,disconnectCard:Y,disconnectIcon:Z,disconnectTitle:ee,disconnectMessage:te,reconnectGuide:se,guideStep:ne,stepNumber:ie,reconnectIndicator:ce,reconnectDot:re,pulse:ae,disconnectActions:oe,btn:le,btnSecondary:de,metricRow:me,metricGrid:ge,metricCard:he,metric_ok:xe,metric_warn:ue,metric_error:ve,metricHeader:_e,metricIcon:pe,metricTitle:fe,metricValue:Ce,metricSubtitle:je,guideCard:we,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:c,subtitle:r,status:a,children:n}){const l=a?s[`metric_${a}`]:"";return t.jsxs("div",{className:`${s.metricCard} ${l}`,children:[t.jsxs("div",{className:s.metricHeader,children:[c&&t.jsx("span",{className:s.metricIcon,children:c}),t.jsx("span",{className:s.metricTitle,children:e})]}),t.jsx("div",{className:s.metricValue,children:i}),r&&t.jsx("div",{className:s.metricSubtitle,children:r}),n]})}function Oe(e){var c,r;const i=e==null?void 0:e.contextSummary;return(i==null?void 0:i.intent)??((r=(c=i==null?void 0:i.affectedAreas)==null?void 0:c[0])==null?void 0:r.label)??(i==null?void 0:i.testScenario)??null}function H({changes:e}){const{t:i}=R(),[c,r]=v.useState(null);return e.length===0?t.jsx("div",{className:s.feedEmpty,children:i("overview.feed.empty")}):t.jsx("div",{className:s.feedList,children:e.map((a,n)=>{const l=c===n,m=a.raw,g=m&&(m.before!=null||m.after!=null||m.details!=null),_=Oe(m);return t.jsxs("div",{children:[t.jsxs("div",{className:`${s.feedItem} ${g?s.feedItemClickable:""}`,onClick:()=>g&&r(l?null:n),children:[t.jsx("span",{className:s.feedTime,children:a.timestamp}),t.jsx("span",{className:s.feedIcon,children:a.icon}),t.jsxs("span",{className:s.feedText,children:[t.jsx("span",{className:s.feedSummary,children:a.summary}),_&&t.jsx("span",{className:s.feedContext,children:_})]}),g&&t.jsx("span",{className:s.feedChevron,children:l?"▴":"▾"})]}),l&&m&&t.jsx("div",{className:s.feedDetail,children:t.jsx(X,{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(),c=F(),[r,a]=v.useState(null),[n,l]=v.useState(null),[m,g]=v.useState(null),[_,h]=v.useState([]),y=v.useRef(null),T=v.useCallback(async()=>{try{const o=await M.get("/connection-info");a(o)}catch{a(null)}},[]),S=v.useCallback(async()=>{try{const o=await M.get("/api/dashboard/changelog/active");if(g(o),o.recentChanges&&o.recentChanges.length>0){const p=o.recentChanges.map(x=>({timestamp:x.timestamp?G(new Date(x.timestamp)):P(),icon:$(x.category),summary:x.summary,category:x.category,raw:x}));h(p)}}catch{g(null)}},[]),f=v.useCallback(async()=>{try{const o=await M.get("/sync/status");l(o)}catch{l(null)}},[]);return v.useEffect(()=>{e!=="disconnected"?(T(),S(),f()):(a(null),l(null),g(null));const o=new V;y.current=o,o.connect();const p=o.on("game_change",C=>{const u=C,j={timestamp:P(),icon:$(u.category),summary:u.summary,category:u.category};h(k=>{const w=[j,...k];return w.length>E?w.slice(0,E):w}),S()}),x=o.on("sync",C=>{const u=C;l(j=>({...j,state:u.status,...u.placeId?{placeId:u.placeId}:{}}))});return()=>{p(),x(),o.disconnect(),y.current=null}},[e,T,S,f]),{level:e,status:i,connectionInfo:r,syncStatus:n,changeSummary:m,recentChanges:_,tier:c}}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,c,r){return t.jsxs("div",{className:e.metricSubtitle,children:[t.jsx(A,{label:i,tooltip:c}),": ",r]},i)}function d(e,i){return t.jsx(O,{text:i,children:e})}function st(){var w,B;const{t:e}=R(),{level:i,status:c,connectionInfo:r,syncStatus:a,changeSummary:n,recentChanges:l}=Xe(),m=q(c==null?void 0:c.uptime),g=t.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 t.jsxs("div",{className:s.page,children:[g,t.jsxs("div",{className:s.disconnectCard,children:[t.jsx("div",{className:s.disconnectIcon,children:"⚠️"}),t.jsx("h2",{className:s.disconnectTitle,children:e("overview.l0.title")}),t.jsx("p",{className:s.disconnectMessage,children:e("overview.l0.message")}),t.jsxs("div",{className:s.reconnectGuide,children:[t.jsxs("div",{className:s.guideStep,children:[t.jsx("span",{className:s.stepNumber,children:"1"}),t.jsx("span",{children:e("overview.l0.step1")})]}),t.jsxs("div",{className:s.guideStep,children:[t.jsx("span",{className:s.stepNumber,children:"2"}),t.jsx("span",{children:e("overview.l0.step2")})]})]}),t.jsxs("div",{className:s.reconnectIndicator,children:[t.jsx("span",{className:s.reconnectDot}),e("overview.l0.reconnecting")]}),t.jsxs("div",{className:s.disconnectActions,children:[t.jsx("button",{className:s.btn,onClick:()=>window.location.reload(),children:e("overview.l0.reconnectBtn")}),t.jsx("button",{className:s.btnSecondary,onClick:()=>{window.location.hash="#/settings"},children:e("overview.l0.settingsBtn")})]})]})]});const _=(r==null?void 0:r.mcpInstanceCount)??0,h=((w=r==null?void 0:r.mcpInstances)==null?void 0:w.find(I=>!I.isServer&&I.aiClientName))??((B=r==null?void 0:r.mcpInstances)==null?void 0:B.find(I=>!!I.aiClientName))??null,y=(c==null?void 0:c.pluginClients)??[],T=y.length>0,S=(c==null?void 0:c.sessionId)??(r==null?void 0:r.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"),p=e("overview.metric.agent.tooltip","Connected AI coding agents and their runtime state"),x=e("overview.metric.sync.tooltip","Current Studio to local sync activity"),C=c?[b(s,e("overview.meta.version","Version"),e("overview.meta.version.tooltip","Installed MCP server version"),`v${c.version}`),b(s,e("overview.meta.session","Session"),e("overview.meta.session.tooltip","Current MCP session identifier"),S),b(s,e("overview.meta.pid","PID"),e("overview.meta.pid.tooltip","Operating system process identifier"),String(c.pid??"-")),b(s,e("overview.meta.uptime","Uptime"),e("overview.meta.uptime.tooltip","Time elapsed since the MCP server started"),J(m??c.uptime))]:[];if(i==="serverOnly")return t.jsxs("div",{className:s.page,children:[g,t.jsxs("div",{className:s.metricRow,children:[t.jsx(N,{title:d(e("overview.metric.server"),f),value:d(e("status.online"),f),icon:"🖥️",status:"ok",children:t.jsxs(t.Fragment,{children:[C,t.jsx(z,{status:"online"})]})}),t.jsx(N,{title:d(e("overview.metric.agent"),p),value:d((h==null?void 0:h.aiClientName)??e("overview.metric.noAgent"),p),icon:"🤖",subtitle:_>1?`${_} ${e("overview.metric.agent.instancesUnit","instances")}`:void 0,status:h?"ok":"warn"})]}),t.jsxs("div",{className:s.guideCard,children:[t.jsx("h3",{className:s.guideTitle,children:e("overview.l1.pluginGuide")}),t.jsxs("ul",{className:s.checklist,children:[t.jsx("li",{children:e("overview.l1.check1")}),t.jsx("li",{children:e("overview.l1.check2")})]})]}),t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.feed.title")}),l.length>0?t.jsx(H,{changes:l}):t.jsx("div",{className:s.feedEmpty,children:e("overview.l1.feedHint")})]}),n&&D(n)>0&&t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.changelog.title")}),t.jsxs("div",{className:s.changelogSummary,children:[t.jsxs("span",{children:[e("overview.changelog.entries","Entries"),": ",D(n)]}),n.scriptsModified>0&&t.jsxs("span",{className:s.changeTag,children:["📝"," ",n.scriptsModified," ",e("overview.changelog.scripts")]}),n.instancesCreated>0&&t.jsxs("span",{className:s.changeTag,children:["🧱"," ",n.instancesCreated," ",e("overview.changelog.instances")]}),n.propertiesChanged>0&&t.jsxs("span",{className:s.changeTag,children:["🎨"," ",n.propertiesChanged," ",e("overview.changelog.properties")]}),n.assetsInserted>0&&t.jsxs("span",{className:s.changeTag,children:["📦"," ",n.assetsInserted," ",e("overview.changelog.assets")]})]})]})]});const u=y[0],j=n?D(n):0,k=!!n&&j>0;return t.jsxs("div",{className:s.page,children:[g,t.jsxs("div",{className:s.metricGrid,children:[t.jsx(N,{title:d(e("overview.metric.server"),f),value:d(e("status.online"),f),icon:"🖥️",status:"ok",children:t.jsx(t.Fragment,{children:C})}),t.jsx(N,{title:d(e("overview.metric.plugin"),o),value:d(e(T?"status.online":"status.offline"),o),icon:"🔌",subtitle:u?`${u.placeName??"-"} / v${u.pluginVersion??"-"}`:void 0,status:T?"ok":"error"}),t.jsx(N,{title:d(e("overview.metric.agent"),p),value:d((h==null?void 0:h.aiClientName)??e("overview.metric.noAgent"),p),icon:"🤖",subtitle:_>1?`${_} ${e("overview.metric.agent.instancesUnit","instances")}`:void 0,status:h?"ok":"warn"}),t.jsx(N,{title:d(e("overview.metric.sync"),x),value:d(qe(a==null?void 0:a.state,e),x),icon:"🔄",status:Je(a==null?void 0:a.state)})]}),t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.feed.title")}),t.jsx(H,{changes:l})]}),k&&t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.changelog.title")}),t.jsxs("div",{className:s.changelogSummary,children:[t.jsxs("span",{children:[e("overview.changelog.entries","Entries"),": ",j]}),n.scriptsModified>0&&t.jsxs("span",{className:s.changeTag,children:["📝"," ",n.scriptsModified," ",e("overview.changelog.scripts")]}),n.instancesCreated>0&&t.jsxs("span",{className:s.changeTag,children:["🧱"," ",n.instancesCreated," ",e("overview.changelog.instances")]}),n.propertiesChanged>0&&t.jsxs("span",{className:s.changeTag,children:["🎨"," ",n.propertiesChanged," ",e("overview.changelog.properties")]}),n.assetsInserted>0&&t.jsxs("span",{className:s.changeTag,children:["📦"," ",n.assetsInserted," ",e("overview.changelog.assets")]})]})]})]})}export{st as Component};
@@ -1 +1 @@
1
- ._button_vab4n_1,._iconButton_vab4n_2{display:inline-flex;align-items:center;justify-content:center;gap:6px;border:1px solid var(--border);border-radius:var(--radius-control);font-family:var(--font-label);font-size:12px;font-weight:600;line-height:1;text-decoration:none;white-space:nowrap;cursor:pointer;transition:background var(--transition),border-color var(--transition),box-shadow var(--transition),color var(--transition),opacity var(--transition)}._button_vab4n_1:focus-visible,._iconButton_vab4n_2:focus-visible,._checkboxInput_vab4n_26:focus-visible{outline:none;box-shadow:var(--focus-ring)}._button_vab4n_1:disabled,._iconButton_vab4n_2:disabled{cursor:not-allowed;opacity:.5}._button_sm_vab4n_37{min-height:28px;padding:0 10px}._button_md_vab4n_42{min-height:34px;padding:0 12px}._primary_vab4n_47{border-color:var(--accent);background:var(--accent);color:var(--button-primary-text)}._primary_vab4n_47:hover:not(:disabled){background:var(--accent-hover);border-color:var(--accent-hover)}._secondary_vab4n_58{background:var(--bg-secondary);color:var(--text-primary)}._secondary_vab4n_58:hover:not(:disabled){border-color:var(--border-highlight);background:var(--accent-dim);color:var(--accent)}._ghost_vab4n_69{border-color:transparent;background:transparent;color:var(--text-secondary)}._ghost_vab4n_69:hover:not(:disabled){border-color:var(--border);background:var(--bg-secondary);color:var(--text-primary)}._danger_vab4n_81{border-color:var(--danger-border);background:var(--danger-bg);color:var(--danger-text)}._danger_vab4n_81:hover:not(:disabled){background:var(--danger-hover-bg);border-color:var(--danger)}._iconButton_vab4n_2{padding:0;background:var(--bg-secondary);color:var(--text-secondary)}._iconButton_vab4n_2:hover:not(:disabled){border-color:var(--border-highlight);background:var(--accent-dim);color:var(--accent)}._iconButton_sm_vab4n_104{width:28px;height:28px}._iconButton_md_vab4n_109{width:34px;height:34px}._badge_vab4n_114{display:inline-flex;align-items:center;justify-content:center;min-height:22px;gap:5px;padding:2px 8px;border:1px solid var(--border);border-radius:var(--radius-control);background:var(--bg-secondary);color:var(--text-secondary);font-family:var(--font-label);font-size:11px;font-weight:600;line-height:1;white-space:nowrap;cursor:default}._pill_vab4n_133{border-radius:var(--radius-pill)}._interactive_vab4n_137{cursor:pointer;transition:background var(--transition),border-color var(--transition),color var(--transition)}._interactive_vab4n_137:hover{border-color:var(--border-highlight);background:var(--accent-dim);color:var(--accent)}._neutral_vab4n_151{background:var(--bg-secondary);border-color:var(--border);color:var(--text-secondary)}._accent_vab4n_157{background:var(--accent-dim);border-color:var(--border-highlight);color:var(--accent)}._success_vab4n_163{background:var(--success-bg);border-color:var(--success-border);color:var(--success-text)}._warning_vab4n_169{background:var(--warning-bg);border-color:var(--warning-border);color:var(--warning-text)}._info_vab4n_175{background:var(--info-bg);border-color:var(--info-border);color:var(--info-text)}._error_vab4n_181{background:var(--error-bg);border-color:var(--error-border);color:var(--error-text)}._danger_vab4n_81._badge_vab4n_114{background:var(--danger-bg);border-color:var(--danger-border);color:var(--danger-text)}._pro_vab4n_193{background:var(--pro-bg-soft);border-color:var(--pro-border);color:var(--pro-text)}._checkboxInput_vab4n_26{width:18px;height:18px;margin:0;border:1px solid var(--border);border-radius:var(--radius-control);accent-color:var(--accent);cursor:pointer}._checkboxInput_vab4n_26:disabled{cursor:not-allowed;opacity:.5}
1
+ ._button_vab4n_1,._iconButton_vab4n_2{display:inline-flex;align-items:center;justify-content:center;gap:6px;border:1px solid var(--border);border-radius:var(--radius-control);font-family:var(--font-label);font-size:12px;font-weight:600;line-height:1;text-decoration:none;white-space:nowrap;cursor:pointer;transition:background var(--transition),border-color var(--transition),box-shadow var(--transition),color var(--transition),opacity var(--transition)}._button_vab4n_1:focus-visible,._iconButton_vab4n_2:focus-visible,._checkboxInput_vab4n_26:focus-visible{outline:none;box-shadow:var(--focus-ring)}._button_vab4n_1:disabled,._iconButton_vab4n_2:disabled{cursor:not-allowed;opacity:.5}._button_sm_vab4n_37{min-height:28px;padding:0 10px}._button_md_vab4n_42{min-height:34px;padding:0 12px}._primary_vab4n_47{border-color:var(--accent);background:var(--accent);color:var(--button-primary-text)}._primary_vab4n_47:hover:not(:disabled){background:var(--accent-hover);border-color:var(--accent-hover)}._secondary_vab4n_58{background:var(--bg-secondary);color:var(--text-primary)}._secondary_vab4n_58:hover:not(:disabled){border-color:var(--border-highlight);background:var(--accent-dim);color:var(--accent)}._ghost_vab4n_69{border-color:transparent;background:transparent;color:var(--text-secondary)}._ghost_vab4n_69:hover:not(:disabled){border-color:var(--border);background:var(--bg-secondary);color:var(--text-primary)}._danger_vab4n_81{border-color:var(--danger-border);background:var(--danger-bg);color:var(--danger-text)}._danger_vab4n_81:hover:not(:disabled){background:var(--danger-hover-bg);border-color:var(--danger)}._iconButton_vab4n_2{padding:0;background:var(--bg-secondary);color:var(--text-secondary)}._iconButton_vab4n_2:hover:not(:disabled){border-color:var(--border-highlight);background:var(--accent-dim);color:var(--accent)}._iconButton_sm_vab4n_104{width:28px;height:28px}._iconButton_md_vab4n_109{width:34px;height:34px}._badge_vab4n_114{display:inline-flex;align-items:center;justify-content:center;min-height:22px;gap:5px;padding:2px 8px;border:1px solid var(--border);border-radius:var(--radius-control);background:var(--bg-secondary);color:var(--text-secondary);font-family:var(--font-label);font-size:11px;font-weight:600;line-height:1;white-space:nowrap;cursor:default}._pill_vab4n_133{border-radius:var(--radius-pill)}._interactive_vab4n_137{cursor:pointer;transition:background var(--transition),border-color var(--transition),color var(--transition)}._interactive_vab4n_137:hover{border-color:var(--border-highlight);background:var(--accent-dim);color:var(--accent)}._neutral_vab4n_151{background:var(--bg-secondary);border-color:var(--border);color:var(--text-secondary)}._accent_vab4n_157{background:var(--accent-dim);border-color:var(--border-highlight);color:var(--accent)}._success_vab4n_163{background:var(--success-bg);border-color:var(--success-border);color:var(--success-text)}._warning_vab4n_169{background:var(--warning-bg);border-color:var(--warning-border);color:var(--warning-text)}._info_vab4n_175{background:var(--info-bg);border-color:var(--info-border);color:var(--info-text)}._error_vab4n_181{background:var(--error-bg);border-color:var(--error-border);color:var(--error-text)}._danger_vab4n_81._badge_vab4n_114{background:var(--danger-bg);border-color:var(--danger-border);color:var(--danger-text)}._pro_vab4n_193{background:var(--pro-bg-soft);border-color:var(--pro-border);color:var(--pro-text)}._checkboxInput_vab4n_26{width:18px;height:18px;margin:0;border:1px solid var(--border);border-radius:var(--radius-control);accent-color:var(--accent);cursor:pointer}._checkboxInput_vab4n_26:disabled{cursor:not-allowed;opacity:.5}._root_15e9p_1{position:relative;display:inline-flex;align-items:center}._rootPage_15e9p_7{margin-left:4px}._rootField_15e9p_11{margin-left:2px}._helpButton_15e9p_15{flex:0 0 auto}._panel_15e9p_19{position:fixed;z-index:1200;box-sizing:border-box;width:min(360px,calc(100vw - 24px));max-height:min(560px,calc(100vh - 24px));overflow:auto;border:1px solid var(--border);border-radius:8px;background:var(--bg-card);box-shadow:0 18px 46px #00000047;padding:14px;text-align:left}._panelField_15e9p_34{width:min(340px,calc(100vw - 24px))}._panelPage_15e9p_38{width:min(360px,calc(100vw - 24px))}._panelHeader_15e9p_42{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:12px}._panelHeader_15e9p_42 h2{margin:0;color:var(--text-primary);font-family:var(--font-label);font-size:14px;line-height:1.3;letter-spacing:0;text-transform:none}._closeButton_15e9p_60{flex:0 0 auto}._sectionStack_15e9p_64{display:grid;gap:12px}._helpSection_15e9p_69 h3,._linkList_15e9p_70 h3{margin:0 0 6px;color:var(--text-primary);font-family:var(--font-label);font-size:12px;letter-spacing:0;text-transform:none}._helpSection_15e9p_69 ul{margin:0;padding-left:18px;color:var(--text-secondary);font-size:12px;line-height:1.45}._helpSection_15e9p_69 li+li{margin-top:4px}._linkList_15e9p_70{display:grid;gap:6px;margin-top:14px;padding-top:12px;border-top:1px solid var(--border)}._linkList_15e9p_70 a{display:inline-flex;align-items:center;gap:6px;color:var(--accent);font-size:12px;text-decoration:none}._linkList_15e9p_70 a:hover,._linkList_15e9p_70 a:focus-visible{text-decoration:underline;outline:none}._pageHeader_qym7v_1{display:flex;align-items:flex-start;justify-content:space-between;gap:20px;min-width:0}._copy_qym7v_9{display:flex;flex-direction:column;gap:5px;min-width:0}._titleLine_qym7v_16{display:flex;align-items:center;gap:8px;min-width:0;flex-wrap:wrap}._titleLine_qym7v_16 h1{margin:0;color:var(--text-primary);font-size:22px;font-weight:700;letter-spacing:0}._copy_qym7v_9 p{margin:0;color:var(--text-secondary);font-size:13px;line-height:1.45}._actions_qym7v_39{display:flex;align-items:center;justify-content:flex-end;flex:0 0 auto}@media(max-width:640px){._pageHeader_qym7v_1{gap:12px}._copy_qym7v_9 p{font-size:12px}}