@weppy/roblox-mcp 2.17.1 → 2.17.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 (44) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dashboard/dist/assets/AiPromptExamples-CJjCcxg8.js +1 -0
  3. package/dashboard/dist/assets/AiPromptExamples-DvVR2a1g.css +1 -0
  4. package/dashboard/dist/assets/AssetsPage-DTiyyQxl.js +61 -0
  5. package/dashboard/dist/assets/AssetsPage-DX8NUPQo.css +1 -0
  6. package/dashboard/dist/assets/{ChangelogPage-CRXXHovV.js → ChangelogPage-DuuVSnIa.js} +1 -1
  7. package/dashboard/dist/assets/{ConfirmModal-Dz7mVKLZ.js → ConfirmModal-DaOuVA6n.js} +1 -1
  8. package/dashboard/dist/assets/{ConnectionPage-CKKn3lt0.js → ConnectionPage-BIq2TqY_.js} +1 -1
  9. package/dashboard/dist/assets/{ControlsPage-Ch6He2CV.js → ControlsPage-DqEbayDU.js} +1 -1
  10. package/dashboard/dist/assets/{CurrentPlaceScope-DhPCqaMU.js → CurrentPlaceScope-p_fkZWK9.js} +1 -1
  11. package/dashboard/dist/assets/{GameChangeDetail-CZuYgFvS.js → GameChangeDetail-BOp_DXQ9.js} +1 -1
  12. package/dashboard/dist/assets/{InfoLabel-BGeOUBIl.js → InfoLabel-gl5i0JQy.js} +1 -1
  13. package/dashboard/dist/assets/{OverviewPage-B-CtTLEP.js → OverviewPage-DcQz5h3p.js} +1 -1
  14. package/dashboard/dist/assets/{PageHeader-CYbeZdtL.js → PageHeader-BkXyqPrA.js} +1 -1
  15. package/dashboard/dist/assets/PlaytestAiPromptExamples-Ciyd-GNB.js +1 -0
  16. package/dashboard/dist/assets/{PlaytestPage-C092tN-C.js → PlaytestPage-CoclFxfc.js} +2 -2
  17. package/dashboard/dist/assets/{SettingsPage-bEHQn_8W.js → SettingsPage-BC0XIU-3.js} +1 -1
  18. package/dashboard/dist/assets/{StatusBadge-BmR5_DsF.js → StatusBadge-BQsRd8hv.js} +1 -1
  19. package/dashboard/dist/assets/{SyncPage-BFz_XQ40.js → SyncPage-DF2YdMPy.js} +1 -1
  20. package/dashboard/dist/assets/{Tabs-C7TenrZD.js → Tabs-Dy5daI-F.js} +1 -1
  21. package/dashboard/dist/assets/{TierPromoPanel-C02VRkHz.js → TierPromoPanel-nA1RBcJp.js} +1 -1
  22. package/dashboard/dist/assets/{ToolsPage-CJeoFakm.js → ToolsPage-DSsqmlnt.js} +1 -1
  23. package/dashboard/dist/assets/{TooltipText-sb-BSgUg.js → TooltipText-BEK9VoiS.js} +1 -1
  24. package/dashboard/dist/assets/UiStudioPage-CiRNdRE-.js +11 -0
  25. package/dashboard/dist/assets/{UiStudioPage-CSK5gQMN.css → UiStudioPage-DdLVbHdA.css} +1 -1
  26. package/dashboard/dist/assets/WhatsNewPage-DX9G9ZFd.js +1 -0
  27. package/dashboard/dist/assets/{bot-oMwejCZF.js → bot-B06rJuWg.js} +1 -1
  28. package/dashboard/dist/assets/{check-EdHXSSef.js → check-CZ_wdz7l.js} +1 -1
  29. package/dashboard/dist/assets/{copy-CePVq0VI.js → copy-CGFMtAPH.js} +1 -1
  30. package/dashboard/dist/assets/{index-DchewB5y.js → index-Hgv8iCTe.js} +36 -36
  31. package/dashboard/dist/assets/{sample-requests-CQvn7a4-.js → sample-requests-DafsjfJi.js} +1 -1
  32. package/dashboard/dist/assets/{trash-2-8V3SCC8q.js → trash-2-DMQtyT_y.js} +1 -1
  33. package/dashboard/dist/assets/{useLiveUptime-BeZ9TLyF.js → useLiveUptime-C6MCUOz0.js} +1 -1
  34. package/dashboard/dist/assets/{useSettings-D5XHMODc.js → useSettings-DfLxtt-w.js} +1 -1
  35. package/dashboard/dist/index.html +1 -1
  36. package/dist/index.js +1 -1
  37. package/package.json +1 -1
  38. package/roblox-plugin/WeppyRobloxMCP.rbxm +0 -0
  39. package/dashboard/dist/assets/AssetsPage-BRZSoLQp.css +0 -1
  40. package/dashboard/dist/assets/AssetsPage-ClzgrkC_.js +0 -56
  41. package/dashboard/dist/assets/PlaytestAiPromptExamples-DHVX0Ljy.css +0 -1
  42. package/dashboard/dist/assets/PlaytestAiPromptExamples-flhav1EU.js +0 -1
  43. package/dashboard/dist/assets/UiStudioPage-C5dYQMax.js +0 -11
  44. package/dashboard/dist/assets/WhatsNewPage-C_z4g3oa.js +0 -1
@@ -1 +1 @@
1
- import{u as P,j as e,d as q,i as z,c as k,r as l,v as K,w as Z,x as J,b as U,s as ee,y as te,h as D,N as ne}from"./index-DchewB5y.js";import{D as Q,P as oe}from"./PageHeader-CYbeZdtL.js";import{I as T}from"./InfoLabel-BGeOUBIl.js";import{s as j}from"./ConfirmModal.module-DJksQHBd.js";import{T as F}from"./TooltipText-sb-BSgUg.js";import{s as t,u as ae}from"./useSettings-D5XHMODc.js";import{C as B}from"./check-EdHXSSef.js";import{C as _}from"./copy-CePVq0VI.js";function H(o,s){return e.jsxs("div",{className:j.pathBlock,children:[e.jsx("span",{className:j.pathLabel,children:o}),e.jsx("code",{className:j.pathCode,children:s})]})}function ie(o){const n=/^[A-Z]:\\/i.test(o)||o.includes("\\")?"\\":"/";return`${o.replace(/[\\/]+$/,"")}${n}weppy-project-sync`}function se({open:o,step:s,selectedProjectRoot:n,studioConnected:d,loading:p=!1,errorMessage:h=null,onClose:a,onPick:c,onApply:g}){const{t:r}=P();if(!o)return null;const y=n?ie(n):"";return e.jsx("div",{className:j.backdrop,onClick:p?void 0:a,role:"presentation",children:e.jsxs("div",{className:j.modal,onClick:x=>x.stopPropagation(),role:"dialog","aria-modal":"true","aria-labelledby":"project-root-change-modal-title",children:[e.jsx("h2",{id:"project-root-change-modal-title",className:j.title,children:s==="initial"?r("header.projectRootModal.initial.title","Change project root"):r("header.projectRootModal.confirm.title","Confirm new project root")}),e.jsx("p",{className:j.message,children:s==="initial"?d?r("header.projectRootModal.initial.body.connected","MCP will switch to the new project root and resync current Studio contents into the new target."):r("header.projectRootModal.initial.body.disconnected","MCP will switch to the new project root and use the new folder as the next sync target."):r("header.projectRootModal.confirm.body","Review the selected project folder before applying.")}),e.jsxs("div",{className:j.bodyGrid,children:[s==="initial"?e.jsxs(e.Fragment,{children:[H(r("header.projectRootModal.initial.nextSyncRoot","New sync target after selection"),r("header.projectRootModal.initial.nextSyncRoot.placeholder","<selected project folder>/weppy-project-sync")),e.jsxs("ul",{className:j.warningList,children:[d?e.jsxs(e.Fragment,{children:[e.jsx("li",{children:r("header.projectRootModal.initial.warningStop","Current sync stops immediately.")}),e.jsx("li",{children:r("header.projectRootModal.initial.warningFreshSync","The current Studio contents will be used to build a fresh full sync in the new target.")})]}):e.jsx("li",{children:r("header.projectRootModal.initial.warningDeferredSync","If Studio is not connected, full resync starts the next time the plugin connects.")}),e.jsx("li",{children:r("header.projectRootModal.initial.warningNoMove","Old sync folders are not moved automatically.")})]})]}):e.jsxs(e.Fragment,{children:[H(r("header.projectRootModal.confirm.projectRoot","Selected project folder"),n??""),H(r("header.projectRootModal.confirm.syncRoot","New sync target"),y),e.jsx("p",{className:j.message,children:r("header.projectRootModal.confirm.warningNoMove","Existing sync folders are not moved automatically.")})]}),h?e.jsx("p",{className:`${j.message} ${j.errorMessage}`,children:h}):null]}),e.jsxs("div",{className:j.actions,children:[e.jsx("button",{className:j.cancelButton,onClick:a,disabled:p,children:r("header.projectRootModal.cancel","Cancel")}),s==="initial"?e.jsx("button",{className:j.confirmButton,onClick:c,disabled:p,children:p?"...":r("header.projectRootModal.pick","Choose folder")}):e.jsx("button",{className:j.confirmButton,onClick:g,disabled:p||!n,children:p?"...":r("header.projectRootModal.apply","Apply change")})]})]})})}function W(o,s){if(o&&typeof o=="object"&&"message"in o&&typeof o.message=="string"){const n=o.message.trim();if(n.length>0)return n}return s}function le(){const{level:o,status:s}=q(),{t:n}=P(),{show:d}=z(),{search:p}=k(),h=l.useRef(null),[a,c]=l.useState(null),[g,r]=l.useState(!1),[y,x]=l.useState(null),[b,N]=l.useState(null),[S,u]=l.useState(!1),[f,v]=l.useState(!1),[L,C]=l.useState(null),M=l.useMemo(()=>new URLSearchParams(p).get("section")==="project-root",[p]),w=l.useCallback(async()=>{if(o==="disconnected"){c(null),r(!1);return}r(!1);try{const m=await K();c(m)}catch{c(null),r(!0)}},[o]);l.useEffect(()=>{w()},[w,s==null?void 0:s.connectedClients,s==null?void 0:s.sessionId]),l.useEffect(()=>{var m,E,V;M&&((E=(m=h.current)==null?void 0:m.scrollIntoView)==null||E.call(m,{block:"start",behavior:"smooth"}),(V=h.current)==null||V.focus())},[M]);const R=(m=!1)=>{!m&&(S||f)||(x(null),N(null),C(null))},i=()=>{o==="disconnected"||!a||(C(null),N(null),x("initial"))},I=async()=>{u(!0),C(null);try{const m=await J();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 Z(b);c(m),r(!1),R(!0)}catch(m){const E=W(m,n("header.projectRootModal.error","Failed to change project root"));C(E),d(E,"error")}finally{v(!1)}}},$=g?n("controls.projectRoot.unavailable","Project root unavailable"):n("common.loading","Loading..."),X=o==="disconnected"||!a;return e.jsxs(e.Fragment,{children:[e.jsxs("div",{id:"controls-project-root",ref:h,tabIndex:-1,className:t.card,children:[e.jsxs("div",{className:t.cardHeader,children:[e.jsx(T,{label:n("controls.projectRoot.title","Project Root"),tooltip:n("controls.projectRoot.title.tooltip","Authoritative project root and sync target used by MCP.")}),e.jsx(F,{text:n("controls.projectRoot.live.tooltip","Changing this updates MCP runtime state immediately after confirmation."),children:e.jsx("span",{className:`${t.headerBadge} ${t.headerBadgeLive}`,children:n("settings.general.liveApply","Live Apply")})})]}),e.jsxs("dl",{className:t.controlGrid,children:[e.jsx("dt",{children:n("controls.projectRoot.projectRoot","Project Root")}),e.jsx("dd",{children:(a==null?void 0:a.projectRoot)??$}),e.jsx("dt",{children:n("controls.projectRoot.syncRoot","Sync Root")}),e.jsx("dd",{children:(a==null?void 0:a.projectSyncRoot)??$})]}),e.jsx("p",{className:t.controlHint,children:n("controls.projectRoot.hint","Use this only when MCP should write sync data under a different project folder. Existing sync folders are not moved automatically.")}),e.jsx("button",{type:"button",className:t.actionBtn,disabled:X,onClick:i,children:n("header.changeProjectRoot","Change Project Root")})]}),e.jsx(se,{open:y!==null,step:y??"initial",selectedProjectRoot:b,studioConnected:o==="studioConnected",loading:S||f,errorMessage:L,onClose:R,onPick:I,onApply:A})]})}function ce(o){if(!o)return null;const s=o.placeName?o.placeId!==void 0?`${o.placeName} · ${o.placeId}`:o.placeName:o.placeId!==void 0?String(o.placeId):null;return s?`${o.targetAlias} · ${s}`:o.targetAlias}function G(o,s){const n=Math.max(0,Math.floor((Date.now()-o)/1e3));return n<60?`${n}${s("connection.time.secondsAgo","s ago")}`:n<3600?`${Math.floor(n/60)}${s("connection.time.minutesAgo","m ago")}`:`${Math.floor(n/3600)}${s("connection.time.hoursAgo","h ago")}`}function re(){const{status:o,level:s}=q(),{t:n}=P(),{show:d}=z(),{search:p}=k(),h=l.useRef(null),a=l.useRef(null),[c,g]=l.useState(null),[r,y]=l.useState(null),[x,b]=l.useState("idle"),N=l.useMemo(()=>new URLSearchParams(p).get("section")==="studio-routing",[p]),S=l.useCallback(async()=>{if(s==="disconnected"){g(null);return}try{const i=await U.get("/api/dashboard/studio-routing");g(i)}catch{g(null)}},[s]);l.useEffect(()=>{S()},[S,o==null?void 0:o.connectedClients,o==null?void 0:o.sessionId]),l.useEffect(()=>{var i,I,A;N&&((I=(i=h.current)==null?void 0:i.scrollIntoView)==null||I.call(i,{block:"start",behavior:"smooth"}),(A=h.current)==null||A.focus())},[N]),l.useEffect(()=>()=>{a.current&&clearTimeout(a.current)},[]);const u=(c==null?void 0:c.studioRoutingMode)??(o==null?void 0:o.studioRoutingMode)??"recentPriority",f=(c==null?void 0:c.pinnedTargetClientId)??(o==null?void 0:o.pinnedTargetClientId)??null,v=ee((c==null?void 0:c.targets)??(o==null?void 0:o.pluginClients)??[],u,f),L=(c==null?void 0:c.priorityTarget)??te(v,u,f),C=ce(L),M=new Set(v.filter(i=>i.placeId!==void 0).map(i=>i.placeId).filter((i,I,A)=>A.filter($=>$===i).length>1)),w=async i=>{y(i.studioRoutingMode==="pinned"?i.pinnedTargetClientId??"pinned":"recentPriority"),b("idle"),a.current&&(clearTimeout(a.current),a.current=null);try{const I=await U.patch("/api/dashboard/studio-routing",i);g(I),b("applied"),a.current=setTimeout(()=>{b("idle"),a.current=null},2e3)}catch{b("failed"),d(n("connection.routing.updateFailed","Failed to update routing target"),"error")}finally{y(null)}},R=async i=>{try{await navigator.clipboard.writeText(i),d(n("connection.targets.copied","Copied value"),"success")}catch{d(n("connection.targets.copyFailed","Failed to copy value"),"error")}};return e.jsxs("div",{id:"controls-studio-routing",ref:h,tabIndex:-1,className:t.card,children:[e.jsxs("div",{className:t.cardHeader,children:[e.jsxs("div",{className:t.cardHeaderTitleGroup,children:[e.jsx("span",{children:n("controls.studioRouting.title","Studio Routing")}),e.jsx(Q,{topicId:"studioRouting",variant:"field",tooltip:n("controls.studioRouting.helpButton","How does it work?"),triggerClassName:`${t.cardHelpButton} ${t.touchTarget44}`})]}),e.jsx("span",{className:`${t.headerBadge} ${t.headerBadgeLive}`,children:n("settings.general.liveApply","Live Apply")})]}),e.jsxs("div",{className:t.routingOverview,children:[e.jsxs("div",{className:t.routingOverviewCopy,children:[e.jsx("span",{className:t.routingEyebrow,children:n("controls.studioRouting.priorityTitle","Priority for requests without a named Studio target")}),e.jsx("strong",{children:u==="pinned"?n("connection.routing.pinned","Manual: Pinned Studio"):n("connection.routing.recentPriority","Automatic: Recent priority")}),e.jsx("p",{children:n("controls.studioRouting.priorityDescription","Explicit Studio ID, Connection ID, or Place ID requests bypass this priority setting and route to the named Studio.")})]}),e.jsxs("div",{className:t.priorityTargetSummary,children:[e.jsx("span",{children:n("controls.studioRouting.state.currentTarget","Current priority target")}),e.jsx("strong",{children:C??n("controls.studioRouting.noPriorityTarget","No connected Studio target")}),e.jsx("span",{className:`${t.savedIndicator} ${t.routingFeedback} ${x==="failed"?t.savedIndicatorFailed:""} ${r===null&&x==="idle"?t.savedIndicatorHidden:""}`,"aria-live":"polite","data-testid":"studio-routing-save-feedback",children:r!==null?n("controls.studioRouting.saving","Applying…"):x==="applied"?n("controls.studioRouting.applied","Applied"):x==="failed"?n("controls.studioRouting.failed","Failed to apply"):null})]})]}),e.jsxs("div",{className:t.studioRoutingChoiceControl,role:"group","aria-label":n("connection.routing.priorityControl","Priority mode for requests without a named Studio target"),children:[e.jsxs("button",{type:"button",className:u==="recentPriority"?t.segmentActive:t.segment,disabled:r!==null,"aria-pressed":u==="recentPriority","aria-label":n("controls.studioRouting.mode.auto","Automatic"),onClick:()=>w({studioRoutingMode:"recentPriority"}),children:[e.jsx("span",{className:t.segmentIndicator,"aria-hidden":"true",children:u==="recentPriority"?e.jsx(B,{size:16}):null}),e.jsxs("span",{className:t.segmentCopy,children:[e.jsx("span",{className:t.segmentLabel,children:n("connection.routing.recentPriority","Automatic: Recent priority")}),e.jsx("small",{className:t.segmentDescription,children:n("controls.studioRouting.help.auto","Automatic uses the highest-priority active Studio, based on recent routed commands and connection order.")})]})]}),e.jsxs("button",{type:"button",className:u==="pinned"?t.segmentActive:t.segment,disabled:!v.length||r!==null,"aria-pressed":u==="pinned","aria-label":n("controls.studioRouting.mode.pinned","Studio fixed"),onClick:()=>w({studioRoutingMode:"pinned"}),children:[e.jsx("span",{className:t.segmentIndicator,"aria-hidden":"true",children:u==="pinned"?e.jsx(B,{size:16}):null}),e.jsxs("span",{className:t.segmentCopy,children:[e.jsx("span",{className:t.segmentLabel,children:n("connection.routing.pinned","Manual: Pinned Studio")}),e.jsx("small",{className:t.segmentDescription,children:n("controls.studioRouting.help.pinned","Studio fixed uses the selected Studio unless the request names a Studio ID, Connection ID, or Place ID.")})]})]})]}),v.length?null:e.jsx("p",{className:t.routingDisabledReason,children:n("controls.studioRouting.pinnedUnavailable","Connect a Studio target to use Studio fixed mode.")}),M.size>0?e.jsx("p",{className:t.routingWarning,children:n("controls.studioRouting.duplicatePlaceWarning","More than one connected Studio window has the same Place ID. Ask the AI agent to use Studio ID for that place.")}):null,e.jsx("div",{className:t.tableWrap,role:u==="pinned"?"radiogroup":void 0,"aria-label":u==="pinned"?n("controls.studioRouting.targetGroupLabel","Studio fixed target"):void 0,children:e.jsxs("table",{className:`${t.table} ${t.routingTargetsTable}`,children:[e.jsxs("colgroup",{children:[e.jsx("col",{className:t.routingActionColumn}),e.jsx("col",{span:6})]}),e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:n("connection.targets.routing","Routing")}),e.jsx("th",{children:n("connection.targets.target","Studio ID")}),e.jsx("th",{children:n("connection.targets.place","Place")}),e.jsx("th",{children:n("connection.targets.placeId","Place ID")}),e.jsx("th",{children:n("connection.targets.lastUsed","Last Used")}),e.jsx("th",{children:n("connection.targets.lastSeen","Last Seen")}),e.jsx("th",{children:n("connection.targets.clientId","Connection ID")})]})}),e.jsx("tbody",{children:v.length>0?v.map(i=>e.jsxs("tr",{children:[e.jsx("td",{children:e.jsx("div",{className:t.routingActionSlot,children:u==="pinned"?e.jsxs("button",{type:"button",role:"radio","aria-checked":f===i.clientId,"aria-label":`${n("controls.studioRouting.selectTarget","Select fixed Studio")}: ${i.targetAlias}`,className:`${t.routingTargetRadio} ${f===i.clientId?t.routingTargetRadioActive:""}`,disabled:r!==null,onClick:()=>{f!==i.clientId&&w({studioRoutingMode:"pinned",pinnedTargetClientId:i.clientId})},children:[e.jsx("span",{className:t.routingRadioIndicator,"aria-hidden":"true",children:f===i.clientId?e.jsx(B,{size:12}):null}),e.jsx("span",{children:f===i.clientId?n("connection.routing.pinnedBadge","Pinned"):n("controls.studioRouting.select","Select")})]}):(L==null?void 0:L.clientId)===i.clientId?e.jsx("span",{className:t.routingBadge,children:n("connection.routing.priorityBadge","Priority")}):null})}),e.jsxs("td",{children:[e.jsx("span",{className:t.monoMuted,title:i.clientId,children:i.targetAlias}),e.jsx(D,{text:n("connection.targets.copyTargetAlias","Copy Studio ID"),children:e.jsx("button",{type:"button",className:t.copyIconButton,"aria-label":n("connection.targets.copyTargetAlias","Copy Studio ID"),onClick:()=>R(i.targetAlias),children:e.jsx(_,{size:13,"aria-hidden":"true"})})})]}),e.jsx("td",{children:i.placeName??"-"}),e.jsxs("td",{children:[i.placeId??"-",i.placeId!==void 0?e.jsx(D,{text:n("connection.targets.copyPlaceId","Copy Place ID"),children:e.jsx("button",{type:"button",className:t.copyIconButton,"aria-label":n("connection.targets.copyPlaceId","Copy Place ID"),onClick:()=>R(String(i.placeId)),children:e.jsx(_,{size:13,"aria-hidden":"true"})})}):null]}),e.jsx("td",{children:i.lastRoutedAt?G(i.lastRoutedAt,n):"-"}),e.jsx("td",{children:G(i.lastSeen,n)}),e.jsxs("td",{children:[e.jsx("span",{className:t.monoMuted,title:i.clientId,children:i.clientId.slice(0,10)}),e.jsx(D,{text:n("connection.targets.copyClientId","Copy Connection ID"),children:e.jsx("button",{type:"button",className:t.copyIconButton,"aria-label":n("connection.targets.copyClientId","Copy Connection ID"),onClick:()=>R(i.clientId),children:e.jsx(_,{size:13,"aria-hidden":"true"})})})]})]},i.clientId)):e.jsx("tr",{children:e.jsx("td",{colSpan:7,className:t.emptyRow,children:n("connection.targets.none","No Studio targets connected. Open Roblox Studio and connect WEPPY Plugin.")})})})]})})]})}const Y=["debug","info","warn","error"];function O({checked:o,onChange:s,testId:n,ariaLabel:d}){return e.jsxs("label",{className:t.toggleSwitch,"data-testid":n,children:[e.jsx("input",{type:"checkbox",className:t.toggleInput,checked:o,"aria-label":d,onChange:p=>s(p.target.checked)}),e.jsx("span",{className:t.toggleTrack,"aria-hidden":"true",children:e.jsx("span",{className:t.toggleThumb})})]})}function de({settings:o,updateHotSetting:s}){const{t:n}=P(),[d,p]=l.useState(null),h=l.useCallback(async(a,c)=>{try{await s(a,c),p(a),setTimeout(()=>p(g=>g===a?null:g),2e3)}catch{p(g=>g===a?null:g)}},[s]);return e.jsxs("div",{className:t.card,children:[e.jsxs("div",{className:t.cardHeader,children:[e.jsx(T,{label:n("settings.general.title","General Settings"),tooltip:n("settings.general.title.tooltip","Hot settings that apply immediately when changed.")}),e.jsx(F,{text:n("settings.general.liveApply.tooltip","Changes in this section are applied immediately without a separate save button."),children:e.jsx("span",{className:`${t.headerBadge} ${t.headerBadgeLive}`,children:n("settings.general.liveApply","Live Apply")})})]}),o?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:t.settingRow,children:[e.jsx("span",{className:t.settingLabel,children:e.jsx(T,{label:n("settings.general.logLevel","Log Level"),tooltip:n("settings.general.logLevel.tooltip","Sets how much detail WEPPY Dashboard writes to its logs.")})}),e.jsxs("div",{className:t.settingControl,children:[e.jsx("select",{className:t.select,value:o.hot.LOG_LEVEL,onChange:a=>{const c=Y.find(g=>g===a.target.value);c&&h("LOG_LEVEL",c)},children:Y.map(a=>e.jsx("option",{value:a,children:a},a))}),d==="LOG_LEVEL"&&e.jsx("span",{className:t.savedIndicator,children:n("settings.general.applied")})]})]}),e.jsxs("div",{className:t.settingRow,children:[e.jsx("span",{className:t.settingLabel,children:e.jsx(T,{label:n("settings.general.localHistory","Tool History Recording"),tooltip:n("settings.general.localHistory.tooltip","Stores local tool execution history for the WEPPY Dashboard history views.")})}),e.jsxs("div",{className:t.settingControl,children:[e.jsx("span",{className:`${t.savedIndicator} ${d==="ENABLE_LOCAL_HISTORY"?"":t.savedIndicatorHidden}`,children:n("settings.general.applied","Applied")}),e.jsx(O,{checked:o.hot.ENABLE_LOCAL_HISTORY,ariaLabel:n("settings.general.localHistory","Tool History Recording"),testId:"settings-toggle-enable-local-history",onChange:a=>h("ENABLE_LOCAL_HISTORY",a)})]})]}),e.jsxs("div",{className:t.settingRow,children:[e.jsx("span",{className:t.settingLabel,children:e.jsx(T,{label:n("settings.general.localStatistics","Tool Statistics Collection"),tooltip:n("settings.general.localStatistics.tooltip","Aggregates local usage statistics for WEPPY Dashboard reporting.")})}),e.jsxs("div",{className:t.settingControl,children:[e.jsx("span",{className:`${t.savedIndicator} ${d==="ENABLE_LOCAL_STATISTICS"?"":t.savedIndicatorHidden}`,children:n("settings.general.applied","Applied")}),e.jsx(O,{checked:o.hot.ENABLE_LOCAL_STATISTICS,ariaLabel:n("settings.general.localStatistics","Tool Statistics Collection"),testId:"settings-toggle-enable-local-statistics",onChange:a=>h("ENABLE_LOCAL_STATISTICS",a)})]})]}),e.jsxs("div",{className:t.settingRow,children:[e.jsx("span",{className:t.settingLabel,children:e.jsx(T,{label:n("settings.general.contextCapture","Context Capture"),tooltip:n("settings.general.contextCapture.tooltip","When enabled, WEPPY Dashboard records structured execution context for changelog and playtest views.")})}),e.jsxs("div",{className:t.settingControl,children:[e.jsx("span",{className:`${t.savedIndicator} ${d==="ENABLE_CONTEXT_CAPTURE"?"":t.savedIndicatorHidden}`,children:n("settings.general.applied","Applied")}),e.jsx(O,{checked:o.hot.ENABLE_CONTEXT_CAPTURE,ariaLabel:n("settings.general.contextCapture","Context Capture"),testId:"settings-toggle-enable-context-capture",onChange:a=>h("ENABLE_CONTEXT_CAPTURE",a)})]})]}),e.jsxs("div",{className:t.settingRow,children:[e.jsx("span",{className:t.settingLabel,children:e.jsx(T,{label:n("settings.general.requestTimeout","Action Timeout"),tooltip:n("settings.general.requestTimeout.tooltip","Maximum time WEPPY Dashboard waits for an action before it fails.")})}),e.jsxs("div",{className:t.settingControl,children:[e.jsx("input",{type:"number",className:t.numberInput,value:o.hot.REQUEST_TIMEOUT,min:1e3,max:12e4,step:1e3,onChange:a=>{const c=parseInt(a.target.value,10);isNaN(c)||h("REQUEST_TIMEOUT",c)}}),e.jsx(F,{text:n("settings.general.requestTimeout.unit.tooltip","Action timeout is measured in milliseconds."),children:e.jsx("span",{className:t.unit,children:n("settings.general.requestTimeout.unit","ms")})}),d==="REQUEST_TIMEOUT"&&e.jsx("span",{className:t.savedIndicator,children:n("settings.general.applied","Applied")})]})]})]}):e.jsx("div",{className:t.loading,children:n("settings.unavailable")})]})}function ue({enabled:o,saving:s,onChange:n}){const{t:d}=P(),{search:p}=k(),h=l.useRef(null),a=l.useRef(null),c=l.useId(),[g,r]=l.useState(!1),[y,x]=l.useState("idle"),b=l.useMemo(()=>new URLSearchParams(p).get("section")==="luau-validation",[p]),N=s||g;l.useEffect(()=>{var u,f,v;b&&((f=(u=h.current)==null?void 0:u.scrollIntoView)==null||f.call(u,{block:"start",behavior:"smooth"}),(v=h.current)==null||v.focus())},[b]),l.useEffect(()=>()=>{a.current&&clearTimeout(a.current)},[]);const S=l.useCallback(async u=>{r(!0),x("idle"),a.current&&(clearTimeout(a.current),a.current=null);try{await n(u),x("applied"),a.current=setTimeout(()=>{x("idle"),a.current=null},2e3)}catch{x("failed")}finally{r(!1)}},[n]);return e.jsxs("div",{id:"controls-luau-validation",ref:h,tabIndex:-1,className:`${t.card} ${t.validationCard}`,"data-testid":"luau-syntax-validation-card",children:[e.jsxs("div",{className:t.cardHeader,children:[e.jsxs("div",{className:t.cardHeaderTitleGroup,children:[e.jsx("span",{children:d("controls.luauValidation.title","Luau Syntax Validation")}),e.jsx(Q,{topicId:"luauValidation",variant:"field",tooltip:d("controls.luauValidation.helpButton","How does it work?"),triggerClassName:`${t.cardHelpButton} ${t.touchTarget44}`})]}),e.jsx("span",{className:`${t.headerBadge} ${t.headerBadgeLive}`,children:d("settings.general.liveApply","Live Apply")})]}),e.jsxs("div",{className:t.validationSettingRow,children:[e.jsxs("div",{className:t.validationSettingCopy,children:[e.jsx("span",{id:c,className:t.validationSettingLabel,children:d("controls.luauValidation.settingLabel","Check automatically after Script edits")}),e.jsx("span",{className:t.validationSettingStatus,children:o?d("controls.luauValidation.state.on","Current: On"):d("controls.luauValidation.state.off","Current: Off")})]}),e.jsxs("div",{className:t.validationPolicyControl,children:[e.jsx("span",{className:`${t.savedIndicator} ${y==="failed"?t.savedIndicatorFailed:""} ${!N&&y==="idle"?t.savedIndicatorHidden:""}`,"data-testid":"luau-validation-save-feedback","aria-live":"polite",children:N?d("controls.luauValidation.saving","Saving…"):y==="applied"?d("controls.luauValidation.applied","Applied"):y==="failed"?d("controls.luauValidation.failed","Failed to apply"):null}),e.jsxs("label",{className:`${t.toggleSwitch} ${t.validationToggleTarget}`,"data-testid":"luau-validation-toggle",children:[e.jsx("input",{type:"checkbox",role:"switch",className:t.toggleInput,checked:o,disabled:N,"aria-labelledby":c,onChange:u=>{S(u.target.checked)}}),e.jsx("span",{className:t.toggleTrack,"aria-hidden":"true",children:e.jsx("span",{className:t.toggleThumb})})]})]})]})]})}function ve(){const{t:o}=P(),{search:s}=k(),{settings:n,updateHotSetting:d,saving:p,loading:h}=ae();return l.useMemo(()=>new URLSearchParams(s).get("section"),[s])==="license"?e.jsx(ne,{to:"/settings?section=license",replace:!0}):h?e.jsx("div",{className:t.page,children:e.jsx("div",{className:t.loading,children:o("common.loading")})}):e.jsxs("div",{className:t.page,children:[e.jsx(oe,{title:o("page.controls.title","Controls"),description:o("page.controls.description","Manage project root, Studio routing, and MCP live settings."),helpTopicId:"controls"}),e.jsx(le,{}),e.jsx(re,{}),e.jsx(ue,{enabled:(n==null?void 0:n.hot.SCRIPT_WRITE_VALIDATION_ENABLED)??!1,saving:p,onChange:c=>d("SCRIPT_WRITE_VALIDATION_ENABLED",c)}),e.jsx(de,{settings:n,updateHotSetting:d})]})}export{ve as Component};
1
+ import{u as P,j as e,d as q,i as z,c as k,r as l,v as K,w as Z,x as J,b as U,s as ee,y as te,h as D,N as ne}from"./index-Hgv8iCTe.js";import{D as Q,P as oe}from"./PageHeader-BkXyqPrA.js";import{I as T}from"./InfoLabel-gl5i0JQy.js";import{s as j}from"./ConfirmModal.module-DJksQHBd.js";import{T as F}from"./TooltipText-BEK9VoiS.js";import{s as t,u as ae}from"./useSettings-DfLxtt-w.js";import{C as B}from"./check-CZ_wdz7l.js";import{C as _}from"./copy-CGFMtAPH.js";function H(o,s){return e.jsxs("div",{className:j.pathBlock,children:[e.jsx("span",{className:j.pathLabel,children:o}),e.jsx("code",{className:j.pathCode,children:s})]})}function ie(o){const n=/^[A-Z]:\\/i.test(o)||o.includes("\\")?"\\":"/";return`${o.replace(/[\\/]+$/,"")}${n}weppy-project-sync`}function se({open:o,step:s,selectedProjectRoot:n,studioConnected:d,loading:p=!1,errorMessage:h=null,onClose:a,onPick:c,onApply:g}){const{t:r}=P();if(!o)return null;const y=n?ie(n):"";return e.jsx("div",{className:j.backdrop,onClick:p?void 0:a,role:"presentation",children:e.jsxs("div",{className:j.modal,onClick:x=>x.stopPropagation(),role:"dialog","aria-modal":"true","aria-labelledby":"project-root-change-modal-title",children:[e.jsx("h2",{id:"project-root-change-modal-title",className:j.title,children:s==="initial"?r("header.projectRootModal.initial.title","Change project root"):r("header.projectRootModal.confirm.title","Confirm new project root")}),e.jsx("p",{className:j.message,children:s==="initial"?d?r("header.projectRootModal.initial.body.connected","MCP will switch to the new project root and resync current Studio contents into the new target."):r("header.projectRootModal.initial.body.disconnected","MCP will switch to the new project root and use the new folder as the next sync target."):r("header.projectRootModal.confirm.body","Review the selected project folder before applying.")}),e.jsxs("div",{className:j.bodyGrid,children:[s==="initial"?e.jsxs(e.Fragment,{children:[H(r("header.projectRootModal.initial.nextSyncRoot","New sync target after selection"),r("header.projectRootModal.initial.nextSyncRoot.placeholder","<selected project folder>/weppy-project-sync")),e.jsxs("ul",{className:j.warningList,children:[d?e.jsxs(e.Fragment,{children:[e.jsx("li",{children:r("header.projectRootModal.initial.warningStop","Current sync stops immediately.")}),e.jsx("li",{children:r("header.projectRootModal.initial.warningFreshSync","The current Studio contents will be used to build a fresh full sync in the new target.")})]}):e.jsx("li",{children:r("header.projectRootModal.initial.warningDeferredSync","If Studio is not connected, full resync starts the next time the plugin connects.")}),e.jsx("li",{children:r("header.projectRootModal.initial.warningNoMove","Old sync folders are not moved automatically.")})]})]}):e.jsxs(e.Fragment,{children:[H(r("header.projectRootModal.confirm.projectRoot","Selected project folder"),n??""),H(r("header.projectRootModal.confirm.syncRoot","New sync target"),y),e.jsx("p",{className:j.message,children:r("header.projectRootModal.confirm.warningNoMove","Existing sync folders are not moved automatically.")})]}),h?e.jsx("p",{className:`${j.message} ${j.errorMessage}`,children:h}):null]}),e.jsxs("div",{className:j.actions,children:[e.jsx("button",{className:j.cancelButton,onClick:a,disabled:p,children:r("header.projectRootModal.cancel","Cancel")}),s==="initial"?e.jsx("button",{className:j.confirmButton,onClick:c,disabled:p,children:p?"...":r("header.projectRootModal.pick","Choose folder")}):e.jsx("button",{className:j.confirmButton,onClick:g,disabled:p||!n,children:p?"...":r("header.projectRootModal.apply","Apply change")})]})]})})}function W(o,s){if(o&&typeof o=="object"&&"message"in o&&typeof o.message=="string"){const n=o.message.trim();if(n.length>0)return n}return s}function le(){const{level:o,status:s}=q(),{t:n}=P(),{show:d}=z(),{search:p}=k(),h=l.useRef(null),[a,c]=l.useState(null),[g,r]=l.useState(!1),[y,x]=l.useState(null),[b,N]=l.useState(null),[S,u]=l.useState(!1),[f,v]=l.useState(!1),[L,C]=l.useState(null),M=l.useMemo(()=>new URLSearchParams(p).get("section")==="project-root",[p]),w=l.useCallback(async()=>{if(o==="disconnected"){c(null),r(!1);return}r(!1);try{const m=await K();c(m)}catch{c(null),r(!0)}},[o]);l.useEffect(()=>{w()},[w,s==null?void 0:s.connectedClients,s==null?void 0:s.sessionId]),l.useEffect(()=>{var m,E,V;M&&((E=(m=h.current)==null?void 0:m.scrollIntoView)==null||E.call(m,{block:"start",behavior:"smooth"}),(V=h.current)==null||V.focus())},[M]);const R=(m=!1)=>{!m&&(S||f)||(x(null),N(null),C(null))},i=()=>{o==="disconnected"||!a||(C(null),N(null),x("initial"))},I=async()=>{u(!0),C(null);try{const m=await J();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 Z(b);c(m),r(!1),R(!0)}catch(m){const E=W(m,n("header.projectRootModal.error","Failed to change project root"));C(E),d(E,"error")}finally{v(!1)}}},$=g?n("controls.projectRoot.unavailable","Project root unavailable"):n("common.loading","Loading..."),X=o==="disconnected"||!a;return e.jsxs(e.Fragment,{children:[e.jsxs("div",{id:"controls-project-root",ref:h,tabIndex:-1,className:t.card,children:[e.jsxs("div",{className:t.cardHeader,children:[e.jsx(T,{label:n("controls.projectRoot.title","Project Root"),tooltip:n("controls.projectRoot.title.tooltip","Authoritative project root and sync target used by MCP.")}),e.jsx(F,{text:n("controls.projectRoot.live.tooltip","Changing this updates MCP runtime state immediately after confirmation."),children:e.jsx("span",{className:`${t.headerBadge} ${t.headerBadgeLive}`,children:n("settings.general.liveApply","Live Apply")})})]}),e.jsxs("dl",{className:t.controlGrid,children:[e.jsx("dt",{children:n("controls.projectRoot.projectRoot","Project Root")}),e.jsx("dd",{children:(a==null?void 0:a.projectRoot)??$}),e.jsx("dt",{children:n("controls.projectRoot.syncRoot","Sync Root")}),e.jsx("dd",{children:(a==null?void 0:a.projectSyncRoot)??$})]}),e.jsx("p",{className:t.controlHint,children:n("controls.projectRoot.hint","Use this only when MCP should write sync data under a different project folder. Existing sync folders are not moved automatically.")}),e.jsx("button",{type:"button",className:t.actionBtn,disabled:X,onClick:i,children:n("header.changeProjectRoot","Change Project Root")})]}),e.jsx(se,{open:y!==null,step:y??"initial",selectedProjectRoot:b,studioConnected:o==="studioConnected",loading:S||f,errorMessage:L,onClose:R,onPick:I,onApply:A})]})}function ce(o){if(!o)return null;const s=o.placeName?o.placeId!==void 0?`${o.placeName} · ${o.placeId}`:o.placeName:o.placeId!==void 0?String(o.placeId):null;return s?`${o.targetAlias} · ${s}`:o.targetAlias}function G(o,s){const n=Math.max(0,Math.floor((Date.now()-o)/1e3));return n<60?`${n}${s("connection.time.secondsAgo","s ago")}`:n<3600?`${Math.floor(n/60)}${s("connection.time.minutesAgo","m ago")}`:`${Math.floor(n/3600)}${s("connection.time.hoursAgo","h ago")}`}function re(){const{status:o,level:s}=q(),{t:n}=P(),{show:d}=z(),{search:p}=k(),h=l.useRef(null),a=l.useRef(null),[c,g]=l.useState(null),[r,y]=l.useState(null),[x,b]=l.useState("idle"),N=l.useMemo(()=>new URLSearchParams(p).get("section")==="studio-routing",[p]),S=l.useCallback(async()=>{if(s==="disconnected"){g(null);return}try{const i=await U.get("/api/dashboard/studio-routing");g(i)}catch{g(null)}},[s]);l.useEffect(()=>{S()},[S,o==null?void 0:o.connectedClients,o==null?void 0:o.sessionId]),l.useEffect(()=>{var i,I,A;N&&((I=(i=h.current)==null?void 0:i.scrollIntoView)==null||I.call(i,{block:"start",behavior:"smooth"}),(A=h.current)==null||A.focus())},[N]),l.useEffect(()=>()=>{a.current&&clearTimeout(a.current)},[]);const u=(c==null?void 0:c.studioRoutingMode)??(o==null?void 0:o.studioRoutingMode)??"recentPriority",f=(c==null?void 0:c.pinnedTargetClientId)??(o==null?void 0:o.pinnedTargetClientId)??null,v=ee((c==null?void 0:c.targets)??(o==null?void 0:o.pluginClients)??[],u,f),L=(c==null?void 0:c.priorityTarget)??te(v,u,f),C=ce(L),M=new Set(v.filter(i=>i.placeId!==void 0).map(i=>i.placeId).filter((i,I,A)=>A.filter($=>$===i).length>1)),w=async i=>{y(i.studioRoutingMode==="pinned"?i.pinnedTargetClientId??"pinned":"recentPriority"),b("idle"),a.current&&(clearTimeout(a.current),a.current=null);try{const I=await U.patch("/api/dashboard/studio-routing",i);g(I),b("applied"),a.current=setTimeout(()=>{b("idle"),a.current=null},2e3)}catch{b("failed"),d(n("connection.routing.updateFailed","Failed to update routing target"),"error")}finally{y(null)}},R=async i=>{try{await navigator.clipboard.writeText(i),d(n("connection.targets.copied","Copied value"),"success")}catch{d(n("connection.targets.copyFailed","Failed to copy value"),"error")}};return e.jsxs("div",{id:"controls-studio-routing",ref:h,tabIndex:-1,className:t.card,children:[e.jsxs("div",{className:t.cardHeader,children:[e.jsxs("div",{className:t.cardHeaderTitleGroup,children:[e.jsx("span",{children:n("controls.studioRouting.title","Studio Routing")}),e.jsx(Q,{topicId:"studioRouting",variant:"field",tooltip:n("controls.studioRouting.helpButton","How does it work?"),triggerClassName:`${t.cardHelpButton} ${t.touchTarget44}`})]}),e.jsx("span",{className:`${t.headerBadge} ${t.headerBadgeLive}`,children:n("settings.general.liveApply","Live Apply")})]}),e.jsxs("div",{className:t.routingOverview,children:[e.jsxs("div",{className:t.routingOverviewCopy,children:[e.jsx("span",{className:t.routingEyebrow,children:n("controls.studioRouting.priorityTitle","Priority for requests without a named Studio target")}),e.jsx("strong",{children:u==="pinned"?n("connection.routing.pinned","Manual: Pinned Studio"):n("connection.routing.recentPriority","Automatic: Recent priority")}),e.jsx("p",{children:n("controls.studioRouting.priorityDescription","Explicit Studio ID, Connection ID, or Place ID requests bypass this priority setting and route to the named Studio.")})]}),e.jsxs("div",{className:t.priorityTargetSummary,children:[e.jsx("span",{children:n("controls.studioRouting.state.currentTarget","Current priority target")}),e.jsx("strong",{children:C??n("controls.studioRouting.noPriorityTarget","No connected Studio target")}),e.jsx("span",{className:`${t.savedIndicator} ${t.routingFeedback} ${x==="failed"?t.savedIndicatorFailed:""} ${r===null&&x==="idle"?t.savedIndicatorHidden:""}`,"aria-live":"polite","data-testid":"studio-routing-save-feedback",children:r!==null?n("controls.studioRouting.saving","Applying…"):x==="applied"?n("controls.studioRouting.applied","Applied"):x==="failed"?n("controls.studioRouting.failed","Failed to apply"):null})]})]}),e.jsxs("div",{className:t.studioRoutingChoiceControl,role:"group","aria-label":n("connection.routing.priorityControl","Priority mode for requests without a named Studio target"),children:[e.jsxs("button",{type:"button",className:u==="recentPriority"?t.segmentActive:t.segment,disabled:r!==null,"aria-pressed":u==="recentPriority","aria-label":n("controls.studioRouting.mode.auto","Automatic"),onClick:()=>w({studioRoutingMode:"recentPriority"}),children:[e.jsx("span",{className:t.segmentIndicator,"aria-hidden":"true",children:u==="recentPriority"?e.jsx(B,{size:16}):null}),e.jsxs("span",{className:t.segmentCopy,children:[e.jsx("span",{className:t.segmentLabel,children:n("connection.routing.recentPriority","Automatic: Recent priority")}),e.jsx("small",{className:t.segmentDescription,children:n("controls.studioRouting.help.auto","Automatic uses the highest-priority active Studio, based on recent routed commands and connection order.")})]})]}),e.jsxs("button",{type:"button",className:u==="pinned"?t.segmentActive:t.segment,disabled:!v.length||r!==null,"aria-pressed":u==="pinned","aria-label":n("controls.studioRouting.mode.pinned","Studio fixed"),onClick:()=>w({studioRoutingMode:"pinned"}),children:[e.jsx("span",{className:t.segmentIndicator,"aria-hidden":"true",children:u==="pinned"?e.jsx(B,{size:16}):null}),e.jsxs("span",{className:t.segmentCopy,children:[e.jsx("span",{className:t.segmentLabel,children:n("connection.routing.pinned","Manual: Pinned Studio")}),e.jsx("small",{className:t.segmentDescription,children:n("controls.studioRouting.help.pinned","Studio fixed uses the selected Studio unless the request names a Studio ID, Connection ID, or Place ID.")})]})]})]}),v.length?null:e.jsx("p",{className:t.routingDisabledReason,children:n("controls.studioRouting.pinnedUnavailable","Connect a Studio target to use Studio fixed mode.")}),M.size>0?e.jsx("p",{className:t.routingWarning,children:n("controls.studioRouting.duplicatePlaceWarning","More than one connected Studio window has the same Place ID. Ask the AI agent to use Studio ID for that place.")}):null,e.jsx("div",{className:t.tableWrap,role:u==="pinned"?"radiogroup":void 0,"aria-label":u==="pinned"?n("controls.studioRouting.targetGroupLabel","Studio fixed target"):void 0,children:e.jsxs("table",{className:`${t.table} ${t.routingTargetsTable}`,children:[e.jsxs("colgroup",{children:[e.jsx("col",{className:t.routingActionColumn}),e.jsx("col",{span:6})]}),e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:n("connection.targets.routing","Routing")}),e.jsx("th",{children:n("connection.targets.target","Studio ID")}),e.jsx("th",{children:n("connection.targets.place","Place")}),e.jsx("th",{children:n("connection.targets.placeId","Place ID")}),e.jsx("th",{children:n("connection.targets.lastUsed","Last Used")}),e.jsx("th",{children:n("connection.targets.lastSeen","Last Seen")}),e.jsx("th",{children:n("connection.targets.clientId","Connection ID")})]})}),e.jsx("tbody",{children:v.length>0?v.map(i=>e.jsxs("tr",{children:[e.jsx("td",{children:e.jsx("div",{className:t.routingActionSlot,children:u==="pinned"?e.jsxs("button",{type:"button",role:"radio","aria-checked":f===i.clientId,"aria-label":`${n("controls.studioRouting.selectTarget","Select fixed Studio")}: ${i.targetAlias}`,className:`${t.routingTargetRadio} ${f===i.clientId?t.routingTargetRadioActive:""}`,disabled:r!==null,onClick:()=>{f!==i.clientId&&w({studioRoutingMode:"pinned",pinnedTargetClientId:i.clientId})},children:[e.jsx("span",{className:t.routingRadioIndicator,"aria-hidden":"true",children:f===i.clientId?e.jsx(B,{size:12}):null}),e.jsx("span",{children:f===i.clientId?n("connection.routing.pinnedBadge","Pinned"):n("controls.studioRouting.select","Select")})]}):(L==null?void 0:L.clientId)===i.clientId?e.jsx("span",{className:t.routingBadge,children:n("connection.routing.priorityBadge","Priority")}):null})}),e.jsxs("td",{children:[e.jsx("span",{className:t.monoMuted,title:i.clientId,children:i.targetAlias}),e.jsx(D,{text:n("connection.targets.copyTargetAlias","Copy Studio ID"),children:e.jsx("button",{type:"button",className:t.copyIconButton,"aria-label":n("connection.targets.copyTargetAlias","Copy Studio ID"),onClick:()=>R(i.targetAlias),children:e.jsx(_,{size:13,"aria-hidden":"true"})})})]}),e.jsx("td",{children:i.placeName??"-"}),e.jsxs("td",{children:[i.placeId??"-",i.placeId!==void 0?e.jsx(D,{text:n("connection.targets.copyPlaceId","Copy Place ID"),children:e.jsx("button",{type:"button",className:t.copyIconButton,"aria-label":n("connection.targets.copyPlaceId","Copy Place ID"),onClick:()=>R(String(i.placeId)),children:e.jsx(_,{size:13,"aria-hidden":"true"})})}):null]}),e.jsx("td",{children:i.lastRoutedAt?G(i.lastRoutedAt,n):"-"}),e.jsx("td",{children:G(i.lastSeen,n)}),e.jsxs("td",{children:[e.jsx("span",{className:t.monoMuted,title:i.clientId,children:i.clientId.slice(0,10)}),e.jsx(D,{text:n("connection.targets.copyClientId","Copy Connection ID"),children:e.jsx("button",{type:"button",className:t.copyIconButton,"aria-label":n("connection.targets.copyClientId","Copy Connection ID"),onClick:()=>R(i.clientId),children:e.jsx(_,{size:13,"aria-hidden":"true"})})})]})]},i.clientId)):e.jsx("tr",{children:e.jsx("td",{colSpan:7,className:t.emptyRow,children:n("connection.targets.none","No Studio targets connected. Open Roblox Studio and connect WEPPY Plugin.")})})})]})})]})}const Y=["debug","info","warn","error"];function O({checked:o,onChange:s,testId:n,ariaLabel:d}){return e.jsxs("label",{className:t.toggleSwitch,"data-testid":n,children:[e.jsx("input",{type:"checkbox",className:t.toggleInput,checked:o,"aria-label":d,onChange:p=>s(p.target.checked)}),e.jsx("span",{className:t.toggleTrack,"aria-hidden":"true",children:e.jsx("span",{className:t.toggleThumb})})]})}function de({settings:o,updateHotSetting:s}){const{t:n}=P(),[d,p]=l.useState(null),h=l.useCallback(async(a,c)=>{try{await s(a,c),p(a),setTimeout(()=>p(g=>g===a?null:g),2e3)}catch{p(g=>g===a?null:g)}},[s]);return e.jsxs("div",{className:t.card,children:[e.jsxs("div",{className:t.cardHeader,children:[e.jsx(T,{label:n("settings.general.title","General Settings"),tooltip:n("settings.general.title.tooltip","Hot settings that apply immediately when changed.")}),e.jsx(F,{text:n("settings.general.liveApply.tooltip","Changes in this section are applied immediately without a separate save button."),children:e.jsx("span",{className:`${t.headerBadge} ${t.headerBadgeLive}`,children:n("settings.general.liveApply","Live Apply")})})]}),o?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:t.settingRow,children:[e.jsx("span",{className:t.settingLabel,children:e.jsx(T,{label:n("settings.general.logLevel","Log Level"),tooltip:n("settings.general.logLevel.tooltip","Sets how much detail WEPPY Dashboard writes to its logs.")})}),e.jsxs("div",{className:t.settingControl,children:[e.jsx("select",{className:t.select,value:o.hot.LOG_LEVEL,onChange:a=>{const c=Y.find(g=>g===a.target.value);c&&h("LOG_LEVEL",c)},children:Y.map(a=>e.jsx("option",{value:a,children:a},a))}),d==="LOG_LEVEL"&&e.jsx("span",{className:t.savedIndicator,children:n("settings.general.applied")})]})]}),e.jsxs("div",{className:t.settingRow,children:[e.jsx("span",{className:t.settingLabel,children:e.jsx(T,{label:n("settings.general.localHistory","Tool History Recording"),tooltip:n("settings.general.localHistory.tooltip","Stores local tool execution history for the WEPPY Dashboard history views.")})}),e.jsxs("div",{className:t.settingControl,children:[e.jsx("span",{className:`${t.savedIndicator} ${d==="ENABLE_LOCAL_HISTORY"?"":t.savedIndicatorHidden}`,children:n("settings.general.applied","Applied")}),e.jsx(O,{checked:o.hot.ENABLE_LOCAL_HISTORY,ariaLabel:n("settings.general.localHistory","Tool History Recording"),testId:"settings-toggle-enable-local-history",onChange:a=>h("ENABLE_LOCAL_HISTORY",a)})]})]}),e.jsxs("div",{className:t.settingRow,children:[e.jsx("span",{className:t.settingLabel,children:e.jsx(T,{label:n("settings.general.localStatistics","Tool Statistics Collection"),tooltip:n("settings.general.localStatistics.tooltip","Aggregates local usage statistics for WEPPY Dashboard reporting.")})}),e.jsxs("div",{className:t.settingControl,children:[e.jsx("span",{className:`${t.savedIndicator} ${d==="ENABLE_LOCAL_STATISTICS"?"":t.savedIndicatorHidden}`,children:n("settings.general.applied","Applied")}),e.jsx(O,{checked:o.hot.ENABLE_LOCAL_STATISTICS,ariaLabel:n("settings.general.localStatistics","Tool Statistics Collection"),testId:"settings-toggle-enable-local-statistics",onChange:a=>h("ENABLE_LOCAL_STATISTICS",a)})]})]}),e.jsxs("div",{className:t.settingRow,children:[e.jsx("span",{className:t.settingLabel,children:e.jsx(T,{label:n("settings.general.contextCapture","Context Capture"),tooltip:n("settings.general.contextCapture.tooltip","When enabled, WEPPY Dashboard records structured execution context for changelog and playtest views.")})}),e.jsxs("div",{className:t.settingControl,children:[e.jsx("span",{className:`${t.savedIndicator} ${d==="ENABLE_CONTEXT_CAPTURE"?"":t.savedIndicatorHidden}`,children:n("settings.general.applied","Applied")}),e.jsx(O,{checked:o.hot.ENABLE_CONTEXT_CAPTURE,ariaLabel:n("settings.general.contextCapture","Context Capture"),testId:"settings-toggle-enable-context-capture",onChange:a=>h("ENABLE_CONTEXT_CAPTURE",a)})]})]}),e.jsxs("div",{className:t.settingRow,children:[e.jsx("span",{className:t.settingLabel,children:e.jsx(T,{label:n("settings.general.requestTimeout","Action Timeout"),tooltip:n("settings.general.requestTimeout.tooltip","Maximum time WEPPY Dashboard waits for an action before it fails.")})}),e.jsxs("div",{className:t.settingControl,children:[e.jsx("input",{type:"number",className:t.numberInput,value:o.hot.REQUEST_TIMEOUT,min:1e3,max:12e4,step:1e3,onChange:a=>{const c=parseInt(a.target.value,10);isNaN(c)||h("REQUEST_TIMEOUT",c)}}),e.jsx(F,{text:n("settings.general.requestTimeout.unit.tooltip","Action timeout is measured in milliseconds."),children:e.jsx("span",{className:t.unit,children:n("settings.general.requestTimeout.unit","ms")})}),d==="REQUEST_TIMEOUT"&&e.jsx("span",{className:t.savedIndicator,children:n("settings.general.applied","Applied")})]})]})]}):e.jsx("div",{className:t.loading,children:n("settings.unavailable")})]})}function ue({enabled:o,saving:s,onChange:n}){const{t:d}=P(),{search:p}=k(),h=l.useRef(null),a=l.useRef(null),c=l.useId(),[g,r]=l.useState(!1),[y,x]=l.useState("idle"),b=l.useMemo(()=>new URLSearchParams(p).get("section")==="luau-validation",[p]),N=s||g;l.useEffect(()=>{var u,f,v;b&&((f=(u=h.current)==null?void 0:u.scrollIntoView)==null||f.call(u,{block:"start",behavior:"smooth"}),(v=h.current)==null||v.focus())},[b]),l.useEffect(()=>()=>{a.current&&clearTimeout(a.current)},[]);const S=l.useCallback(async u=>{r(!0),x("idle"),a.current&&(clearTimeout(a.current),a.current=null);try{await n(u),x("applied"),a.current=setTimeout(()=>{x("idle"),a.current=null},2e3)}catch{x("failed")}finally{r(!1)}},[n]);return e.jsxs("div",{id:"controls-luau-validation",ref:h,tabIndex:-1,className:`${t.card} ${t.validationCard}`,"data-testid":"luau-syntax-validation-card",children:[e.jsxs("div",{className:t.cardHeader,children:[e.jsxs("div",{className:t.cardHeaderTitleGroup,children:[e.jsx("span",{children:d("controls.luauValidation.title","Luau Syntax Validation")}),e.jsx(Q,{topicId:"luauValidation",variant:"field",tooltip:d("controls.luauValidation.helpButton","How does it work?"),triggerClassName:`${t.cardHelpButton} ${t.touchTarget44}`})]}),e.jsx("span",{className:`${t.headerBadge} ${t.headerBadgeLive}`,children:d("settings.general.liveApply","Live Apply")})]}),e.jsxs("div",{className:t.validationSettingRow,children:[e.jsxs("div",{className:t.validationSettingCopy,children:[e.jsx("span",{id:c,className:t.validationSettingLabel,children:d("controls.luauValidation.settingLabel","Check automatically after Script edits")}),e.jsx("span",{className:t.validationSettingStatus,children:o?d("controls.luauValidation.state.on","Current: On"):d("controls.luauValidation.state.off","Current: Off")})]}),e.jsxs("div",{className:t.validationPolicyControl,children:[e.jsx("span",{className:`${t.savedIndicator} ${y==="failed"?t.savedIndicatorFailed:""} ${!N&&y==="idle"?t.savedIndicatorHidden:""}`,"data-testid":"luau-validation-save-feedback","aria-live":"polite",children:N?d("controls.luauValidation.saving","Saving…"):y==="applied"?d("controls.luauValidation.applied","Applied"):y==="failed"?d("controls.luauValidation.failed","Failed to apply"):null}),e.jsxs("label",{className:`${t.toggleSwitch} ${t.validationToggleTarget}`,"data-testid":"luau-validation-toggle",children:[e.jsx("input",{type:"checkbox",role:"switch",className:t.toggleInput,checked:o,disabled:N,"aria-labelledby":c,onChange:u=>{S(u.target.checked)}}),e.jsx("span",{className:t.toggleTrack,"aria-hidden":"true",children:e.jsx("span",{className:t.toggleThumb})})]})]})]})]})}function ve(){const{t:o}=P(),{search:s}=k(),{settings:n,updateHotSetting:d,saving:p,loading:h}=ae();return l.useMemo(()=>new URLSearchParams(s).get("section"),[s])==="license"?e.jsx(ne,{to:"/settings?section=license",replace:!0}):h?e.jsx("div",{className:t.page,children:e.jsx("div",{className:t.loading,children:o("common.loading")})}):e.jsxs("div",{className:t.page,children:[e.jsx(oe,{title:o("page.controls.title","Controls"),description:o("page.controls.description","Manage project root, Studio routing, and MCP live settings."),helpTopicId:"controls"}),e.jsx(le,{}),e.jsx(re,{}),e.jsx(ue,{enabled:(n==null?void 0:n.hot.SCRIPT_WRITE_VALIDATION_ENABLED)??!1,saving:p,onChange:c=>d("SCRIPT_WRITE_VALIDATION_ENABLED",c)}),e.jsx(de,{settings:n,updateHotSetting:d})]})}export{ve as Component};
@@ -1 +1 @@
1
- import{u as m,r as f,j as c,g as _}from"./index-DchewB5y.js";import{B as x}from"./PageHeader-CYbeZdtL.js";const j="_scope_to3mp_1",I="_main_to3mp_13",w="_label_to3mp_20",A="_selectorLabel_to3mp_28",L="_placeSelect_to3mp_35",k="_name_to3mp_48",y="_id_to3mp_59",E="_scopeBadge_to3mp_66",B="_copy_to3mp_70",U="_note_to3mp_82",n={scope:j,main:I,label:w,selectorLabel:A,placeSelect:L,name:k,id:y,scopeBadge:E,copy:B,note:U};function d(e,l){return l===null?null:e.places.find(a=>a.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 N(e){return e.pluginConnected&&e.activePlaceId!==null?e.activePlaceId:S(e)}function q(e,l){if(e.pluginConnected&&e.activePlaceId!==null){const t=d(e,e.activePlaceId);return{label:l("placeScope.current.label","Current Place"),placeId:e.activePlaceId,placeName:e.activePlaceName??(t==null?void 0:t.placeName)??l("placeScope.unknownPlace","Unknown place"),badge:l("placeScope.live","Live"),live:!0,note:null}}const a=S(e),s=d(e,a);if(a!==null){const t=a===e.lastActivePlaceId?e.lastActivePlaceName:null;return{label:l("placeScope.lastActive.label","Last Active Place"),placeId:a,placeName:t??(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 F(e,l,a){const s=typeof l=="number"?d(e,l):null,t=N(e),o=(s==null?void 0:s.placeId)??t,r=d(e,o);if(o===null)return{label:a("placeScope.noPlace.label","Place scope"),placeId:null,placeName:a("placeScope.noPlace.value","No place data available yet"),badge:a("placeScope.noPlace.badge","No place"),live:!1,note:a("placeScope.noPlace.note","Connect WEPPY Plugin and sync a place to create place-scoped data.")};const u=e.pluginConnected&&e.activePlaceId===o,b=o===e.lastActivePlaceId?e.lastActivePlaceName:null;return{label:u?a("placeScope.current.label","Current Place"):a("placeScope.selected.label","Selected Place"),placeId:o,placeName:(r==null?void 0:r.placeName)??b??a("placeScope.unknownPlace","Unknown place"),badge:u?a("placeScope.live","Live"):a("placeScope.stored","Stored"),live:u,note:u?null:a("placeScope.selected.note","Showing stored data only. Studio routing is unchanged.")}}function R(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 Y({surface:e,selectable:l=!1,selectedPlaceId:a=null,onSelectedPlaceIdChange:s}){const{t}=m(),[o,r]=f.useState(null),[u,b]=f.useState(!0);if(f.useEffect(()=>{let p=!1;async function v(){try{const h=await _();p||r(h)}catch{p||r(null)}finally{p||b(!1)}}return v(),()=>{p=!0}},[]),f.useEffect(()=>{if(!l||!o)return;const p=N(o);(typeof a!="number"||!d(o,a))&&a!==p&&(s==null||s(p))},[s,l,a,o]),u)return c.jsx("div",{className:n.scope,"aria-live":"polite",children:c.jsx("span",{className:n.label,children:t("placeScope.loading","Loading place scope...")})});if(!o)return c.jsx("div",{className:n.scope,"aria-live":"polite",children:c.jsx("span",{className:n.label,children:t("placeScope.unavailable","Place scope unavailable")})});const i=l?F(o,a,t):q(o,t),P=typeof i.placeId=="number"?String(i.placeId):"",g=l&&o.places.length>0;return c.jsxs("div",{className:n.scope,"aria-live":"polite",children:[c.jsxs("div",{className:n.main,children:[g?c.jsxs(c.Fragment,{children:[c.jsxs("label",{className:n.selectorLabel,children:[c.jsx("span",{className:n.label,children:t("placeScope.selector.label","Place data")}),c.jsx("select",{className:n.placeSelect,value:P,onChange:p=>{const v=Number.parseInt(p.currentTarget.value,10);s==null||s(Number.isInteger(v)?v:null)},children:o.places.map(p=>c.jsxs("option",{value:p.placeId,children:[p.placeName," (",p.placeId,")"]},p.placeId))})]}),c.jsx("span",{className:n.label,children:i.label}),c.jsx("span",{className:n.name,children:i.placeName})]}):c.jsxs(c.Fragment,{children:[c.jsx("span",{className:n.label,children:i.label}),c.jsx("span",{className:n.name,children:i.placeName})]}),i.placeId!==null?c.jsx("span",{className:n.id,children:i.placeId}):null,c.jsx(x,{variant:i.live?"success":"warning",shape:"pill",className:n.scopeBadge,children:i.badge})]}),c.jsxs("div",{className:n.copy,children:[c.jsx("span",{children:R(e,t)}),i.note?c.jsx("span",{className:n.note,children:i.note}):null]})]})}export{Y as C};
1
+ import{u as m,r as f,j as c,g as _}from"./index-Hgv8iCTe.js";import{B as x}from"./PageHeader-BkXyqPrA.js";const j="_scope_to3mp_1",I="_main_to3mp_13",w="_label_to3mp_20",A="_selectorLabel_to3mp_28",L="_placeSelect_to3mp_35",k="_name_to3mp_48",y="_id_to3mp_59",E="_scopeBadge_to3mp_66",B="_copy_to3mp_70",U="_note_to3mp_82",n={scope:j,main:I,label:w,selectorLabel:A,placeSelect:L,name:k,id:y,scopeBadge:E,copy:B,note:U};function d(e,l){return l===null?null:e.places.find(a=>a.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 N(e){return e.pluginConnected&&e.activePlaceId!==null?e.activePlaceId:S(e)}function q(e,l){if(e.pluginConnected&&e.activePlaceId!==null){const t=d(e,e.activePlaceId);return{label:l("placeScope.current.label","Current Place"),placeId:e.activePlaceId,placeName:e.activePlaceName??(t==null?void 0:t.placeName)??l("placeScope.unknownPlace","Unknown place"),badge:l("placeScope.live","Live"),live:!0,note:null}}const a=S(e),s=d(e,a);if(a!==null){const t=a===e.lastActivePlaceId?e.lastActivePlaceName:null;return{label:l("placeScope.lastActive.label","Last Active Place"),placeId:a,placeName:t??(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 F(e,l,a){const s=typeof l=="number"?d(e,l):null,t=N(e),o=(s==null?void 0:s.placeId)??t,r=d(e,o);if(o===null)return{label:a("placeScope.noPlace.label","Place scope"),placeId:null,placeName:a("placeScope.noPlace.value","No place data available yet"),badge:a("placeScope.noPlace.badge","No place"),live:!1,note:a("placeScope.noPlace.note","Connect WEPPY Plugin and sync a place to create place-scoped data.")};const u=e.pluginConnected&&e.activePlaceId===o,b=o===e.lastActivePlaceId?e.lastActivePlaceName:null;return{label:u?a("placeScope.current.label","Current Place"):a("placeScope.selected.label","Selected Place"),placeId:o,placeName:(r==null?void 0:r.placeName)??b??a("placeScope.unknownPlace","Unknown place"),badge:u?a("placeScope.live","Live"):a("placeScope.stored","Stored"),live:u,note:u?null:a("placeScope.selected.note","Showing stored data only. Studio routing is unchanged.")}}function R(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 Y({surface:e,selectable:l=!1,selectedPlaceId:a=null,onSelectedPlaceIdChange:s}){const{t}=m(),[o,r]=f.useState(null),[u,b]=f.useState(!0);if(f.useEffect(()=>{let p=!1;async function v(){try{const h=await _();p||r(h)}catch{p||r(null)}finally{p||b(!1)}}return v(),()=>{p=!0}},[]),f.useEffect(()=>{if(!l||!o)return;const p=N(o);(typeof a!="number"||!d(o,a))&&a!==p&&(s==null||s(p))},[s,l,a,o]),u)return c.jsx("div",{className:n.scope,"aria-live":"polite",children:c.jsx("span",{className:n.label,children:t("placeScope.loading","Loading place scope...")})});if(!o)return c.jsx("div",{className:n.scope,"aria-live":"polite",children:c.jsx("span",{className:n.label,children:t("placeScope.unavailable","Place scope unavailable")})});const i=l?F(o,a,t):q(o,t),P=typeof i.placeId=="number"?String(i.placeId):"",g=l&&o.places.length>0;return c.jsxs("div",{className:n.scope,"aria-live":"polite",children:[c.jsxs("div",{className:n.main,children:[g?c.jsxs(c.Fragment,{children:[c.jsxs("label",{className:n.selectorLabel,children:[c.jsx("span",{className:n.label,children:t("placeScope.selector.label","Place data")}),c.jsx("select",{className:n.placeSelect,value:P,onChange:p=>{const v=Number.parseInt(p.currentTarget.value,10);s==null||s(Number.isInteger(v)?v:null)},children:o.places.map(p=>c.jsxs("option",{value:p.placeId,children:[p.placeName," (",p.placeId,")"]},p.placeId))})]}),c.jsx("span",{className:n.label,children:i.label}),c.jsx("span",{className:n.name,children:i.placeName})]}):c.jsxs(c.Fragment,{children:[c.jsx("span",{className:n.label,children:i.label}),c.jsx("span",{className:n.name,children:i.placeName})]}),i.placeId!==null?c.jsx("span",{className:n.id,children:i.placeId}):null,c.jsx(x,{variant:i.live?"success":"warning",shape:"pill",className:n.scopeBadge,children:i.badge})]}),c.jsxs("div",{className:n.copy,children:[c.jsx("span",{children:R(e,t)}),i.note?c.jsx("span",{className:n.note,children:i.note}):null]})]})}export{Y as C};
@@ -1,4 +1,4 @@
1
- import{u as _,r as x,j as e}from"./index-DchewB5y.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-Hgv8iCTe.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,h as e}from"./index-DchewB5y.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-Hgv8iCTe.js";function s({label:t,tooltip:o}){return r.jsx(e,{text:o,children:t})}export{s as I};
@@ -1 +1 @@
1
- import{j as s,u as R,r as h,d as L,e as F,b as M,D as V}from"./index-DchewB5y.js";import{I as A}from"./InfoLabel-BGeOUBIl.js";import{P as U}from"./PageHeader-CYbeZdtL.js";import{S as z}from"./StatusBadge-BmR5_DsF.js";import{T as O}from"./TooltipText-sb-BSgUg.js";import{G as X}from"./GameChangeDetail-CZuYgFvS.js";import{u as q,f as J}from"./useLiveUptime-BeZ9TLyF.js";const K="_page_amwos_2",Q="_card_amwos_10",W="_cardHeader_amwos_17",Y="_disconnectCard_amwos_28",Z="_disconnectIcon_amwos_36",ee="_disconnectTitle_amwos_41",se="_disconnectMessage_amwos_48",te="_reconnectGuide_amwos_55",ne="_guideStep_amwos_64",ie="_stepNumber_amwos_72",ae="_reconnectIndicator_amwos_88",ce="_reconnectDot_amwos_98",re="_pulse_amwos_1",oe="_disconnectActions_amwos_112",le="_btn_amwos_118",de="_btnSecondary_amwos_134",me="_metricRow_amwos_152",ue="_metricGrid_amwos_158",ve="_metricCard_amwos_164",ge="_metric_ok_amwos_174",_e="_metric_warn_amwos_179",he="_metric_error_amwos_184",pe="_metricHeader_amwos_189",we="_metricIcon_amwos_200",fe="_metricTitle_amwos_204",xe="_metricValue_amwos_208",Ce="_metricSubtitle_amwos_215",je="_guideCard_amwos_225",Ne="_guideTitle_amwos_232",ye="_checklist_amwos_239",Te="_feedEmpty_amwos_263",Se="_feedList_amwos_270",Ie="_feedItem_amwos_278",be="_feedTime_amwos_291",ke="_feedIcon_amwos_298",Me="_feedSummary_amwos_304",De="_feedText_amwos_313",Be="_feedContext_amwos_321",He="_feedItemClickable_amwos_330",Ee="_feedChevron_amwos_338",Pe="_feedDetail_amwos_347",$e="_feedDetailPre_amwos_356",Re="_feedDetailText_amwos_365",Ge="_changelogSummary_amwos_372",Le="_changeTag_amwos_381",Fe="_tierBar_amwos_393",Ve="_tierBarTrack_amwos_399",Ae="_tierBarFillBasic_amwos_407",Ue="_tierBarFillPro_amwos_412",ze="_tierLabels_amwos_417",t={page:K,card:Q,cardHeader:W,disconnectCard:Y,disconnectIcon:Z,disconnectTitle:ee,disconnectMessage:se,reconnectGuide:te,guideStep:ne,stepNumber:ie,reconnectIndicator:ae,reconnectDot:ce,pulse:re,disconnectActions:oe,btn:le,btnSecondary:de,metricRow:me,metricGrid:ue,metricCard:ve,metric_ok:ge,metric_warn:_e,metric_error:he,metricHeader:pe,metricIcon:we,metricTitle:fe,metricValue:xe,metricSubtitle:Ce,guideCard:je,guideTitle:Ne,checklist:ye,feedEmpty:Te,feedList:Se,feedItem:Ie,feedTime:be,feedIcon:ke,feedSummary:Me,feedText:De,feedContext:Be,feedItemClickable:He,feedChevron:Ee,feedDetail:Pe,feedDetailPre:$e,feedDetailText:Re,changelogSummary:Ge,changeTag:Le,tierBar:Fe,tierBarTrack:Ve,tierBarFillBasic:Ae,tierBarFillPro:Ue,tierLabels:ze};function N({title:e,value:i,icon:a,subtitle:c,status:r,children:n}){const l=r?t[`metric_${r}`]:"";return s.jsxs("div",{className:`${t.metricCard} ${l}`,children:[s.jsxs("div",{className:t.metricHeader,children:[a&&s.jsx("span",{className:t.metricIcon,children:a}),s.jsx("span",{className:t.metricTitle,children:e})]}),s.jsx("div",{className:t.metricValue,children:i}),c&&s.jsx("div",{className:t.metricSubtitle,children:c}),n]})}function Oe(e){var a,c;const i=e==null?void 0:e.contextSummary;return(i==null?void 0:i.intent)??((c=(a=i==null?void 0:i.affectedAreas)==null?void 0:a[0])==null?void 0:c.label)??(i==null?void 0:i.testScenario)??null}function H({changes:e}){const{t:i}=R(),[a,c]=h.useState(null);return e.length===0?s.jsx("div",{className:t.feedEmpty,children:i("overview.feed.empty")}):s.jsx("div",{className:t.feedList,children:e.map((r,n)=>{const l=a===n,m=r.raw,u=m&&(m.before!=null||m.after!=null||m.details!=null),p=Oe(m);return s.jsxs("div",{children:[s.jsxs("div",{className:`${t.feedItem} ${u?t.feedItemClickable:""}`,onClick:()=>u&&c(l?null:n),children:[s.jsx("span",{className:t.feedTime,children:r.timestamp}),s.jsx("span",{className:t.feedIcon,children:r.icon}),s.jsxs("span",{className:t.feedText,children:[s.jsx("span",{className:t.feedSummary,children:r.summary}),p&&s.jsx("span",{className:t.feedContext,children:p})]}),u&&s.jsx("span",{className:t.feedChevron,children:l?"▴":"▾"})]}),l&&m&&s.jsx("div",{className:t.feedDetail,children:s.jsx(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(),a=F(),[c,r]=h.useState(null),[n,l]=h.useState(null),[m,u]=h.useState(null),[p,v]=h.useState([]),y=h.useRef(null),T=h.useCallback(async()=>{try{const o=await M.get("/connection-info");r(o)}catch{r(null)}},[]),S=h.useCallback(async()=>{try{const o=await M.get("/api/dashboard/changelog/active");if(u(o),o.recentChanges&&o.recentChanges.length>0){const w=o.recentChanges.map(g=>({timestamp:g.timestamp?G(new Date(g.timestamp)):P(),icon:$(g.category),summary:g.summary,category:g.category,raw:g}));v(w)}}catch{u(null)}},[]),f=h.useCallback(async()=>{try{const o=await M.get("/sync/status");l(o)}catch{l(null)}},[]);return h.useEffect(()=>{e!=="disconnected"?(T(),S(),f()):(r(null),l(null),u(null));const o=new V;y.current=o,o.connect();const w=o.on("game_change",x=>{const _=x,C={timestamp:P(),icon:$(_.category),summary:_.summary,category:_.category};v(k=>{const j=[C,...k];return j.length>E?j.slice(0,E):j}),S()}),g=o.on("sync",x=>{const _=x;l(C=>({...C,state:_.status,..._.placeId?{placeId:_.placeId}:{}}))});return()=>{w(),g(),o.disconnect(),y.current=null}},[e,T,S,f]),{level:e,status:i,connectionInfo:c,syncStatus:n,changeSummary:m,recentChanges:p,tier:a}}function D(e){return e.scriptsModified+e.scriptsCreated+e.instancesCreated+e.instancesDeleted+e.instancesMoved+e.propertiesChanged+e.assetsInserted+(e.lightingChanged?1:0)+(e.terrainChanged?1:0)}function qe(e,i){switch(e){case"syncing":return i("status.syncing","Syncing");case"initializing":return i("status.initializing","Initializing");case"error":return i("status.error","Error");default:return i("status.idle","Idle")}}function Je(e){switch(e){case"syncing":return"ok";case"initializing":return"warn";case"error":return"error";default:return"ok"}}function b(e,i,a,c){return s.jsxs("div",{className:e.metricSubtitle,children:[s.jsx(A,{label:i,tooltip:a}),": ",c]},i)}function d(e,i){return s.jsx(O,{text:i,children:e})}function ts(){var j,B;const{t:e}=R(),{level:i,status:a,connectionInfo:c,syncStatus:r,changeSummary:n,recentChanges:l}=Xe(),m=q(a==null?void 0:a.uptime),u=s.jsx(U,{title:e("page.overview.title","Overview"),description:e("page.overview.description","Check server, plugin, agent, sync, and recent game-change status in one place."),helpTopicId:"overview",helpState:{connectionLevel:i}});if(i==="disconnected")return s.jsxs("div",{className:t.page,children:[u,s.jsxs("div",{className:t.disconnectCard,children:[s.jsx("div",{className:t.disconnectIcon,children:"⚠️"}),s.jsx("h2",{className:t.disconnectTitle,children:e("overview.l0.title")}),s.jsx("p",{className:t.disconnectMessage,children:e("overview.l0.message")}),s.jsxs("div",{className:t.reconnectGuide,children:[s.jsxs("div",{className:t.guideStep,children:[s.jsx("span",{className:t.stepNumber,children:"1"}),s.jsx("span",{children:e("overview.l0.step1")})]}),s.jsxs("div",{className:t.guideStep,children:[s.jsx("span",{className:t.stepNumber,children:"2"}),s.jsx("span",{children:e("overview.l0.step2")})]})]}),s.jsxs("div",{className:t.reconnectIndicator,children:[s.jsx("span",{className:t.reconnectDot}),e("overview.l0.reconnecting")]}),s.jsxs("div",{className:t.disconnectActions,children:[s.jsx("button",{className:t.btn,onClick:()=>window.location.reload(),children:e("overview.l0.reconnectBtn")}),s.jsx("button",{className:t.btnSecondary,onClick:()=>{window.location.hash="#/settings"},children:e("overview.l0.settingsBtn")})]})]})]});const p=(c==null?void 0:c.mcpInstanceCount)??0,v=((j=c==null?void 0:c.mcpInstances)==null?void 0:j.find(I=>!I.isServer&&I.aiClientName))??((B=c==null?void 0:c.mcpInstances)==null?void 0:B.find(I=>!!I.aiClientName))??null,y=(a==null?void 0:a.pluginClients)??[],T=y.length>0,S=(a==null?void 0:a.sessionId)??(c==null?void 0:c.sessionId)??"-",f=e("overview.metric.server.tooltip","MCP server runtime and process status"),o=e("overview.metric.plugin.tooltip","Roblox Studio plugin connection and version status"),w=e("overview.metric.agent.tooltip","Connected AI coding agents and their runtime state"),g=e("overview.metric.sync.tooltip","Current Studio to local sync activity"),x=a?[b(t,e("overview.meta.version","Version"),e("overview.meta.version.tooltip","Installed MCP server version"),`v${a.version}`),b(t,e("overview.meta.session","Session"),e("overview.meta.session.tooltip","Current MCP session identifier"),S),b(t,e("overview.meta.pid","PID"),e("overview.meta.pid.tooltip","Operating system process identifier"),String(a.pid??"-")),b(t,e("overview.meta.uptime","Uptime"),e("overview.meta.uptime.tooltip","Time elapsed since the MCP server started"),J(m??a.uptime))]:[];if(i==="serverOnly")return s.jsxs("div",{className:t.page,children:[u,s.jsxs("div",{className:t.metricRow,children:[s.jsx(N,{title:d(e("overview.metric.server"),f),value:d(e("status.online"),f),icon:"🖥️",status:"ok",children:s.jsxs(s.Fragment,{children:[x,s.jsx(z,{status:"online"})]})}),s.jsx(N,{title:d(e("overview.metric.agent"),w),value:d((v==null?void 0:v.aiClientName)??e("overview.metric.noAgent"),w),icon:"🤖",subtitle:p>1?`${p} ${e("overview.metric.agent.instancesUnit","instances")}`:void 0,status:v?"ok":"warn"})]}),s.jsxs("div",{className:t.guideCard,children:[s.jsx("h3",{className:t.guideTitle,children:e("overview.l1.pluginGuide")}),s.jsxs("ul",{className:t.checklist,children:[s.jsx("li",{children:e("overview.l1.check1")}),s.jsx("li",{children:e("overview.l1.check2")})]})]}),s.jsxs("div",{className:t.card,children:[s.jsx("div",{className:t.cardHeader,children:e("overview.feed.title")}),l.length>0?s.jsx(H,{changes:l}):s.jsx("div",{className:t.feedEmpty,children:e("overview.l1.feedHint")})]}),n&&D(n)>0&&s.jsxs("div",{className:t.card,children:[s.jsx("div",{className:t.cardHeader,children:e("overview.changelog.title")}),s.jsxs("div",{className:t.changelogSummary,children:[s.jsxs("span",{children:[e("overview.changelog.entries","Entries"),": ",D(n)]}),n.scriptsModified>0&&s.jsxs("span",{className:t.changeTag,children:["📝"," ",n.scriptsModified," ",e("overview.changelog.scripts")]}),n.instancesCreated>0&&s.jsxs("span",{className:t.changeTag,children:["🧱"," ",n.instancesCreated," ",e("overview.changelog.instances")]}),n.propertiesChanged>0&&s.jsxs("span",{className:t.changeTag,children:["🎨"," ",n.propertiesChanged," ",e("overview.changelog.properties")]}),n.assetsInserted>0&&s.jsxs("span",{className:t.changeTag,children:["📦"," ",n.assetsInserted," ",e("overview.changelog.assets")]})]})]})]});const _=y[0],C=n?D(n):0,k=!!n&&C>0;return s.jsxs("div",{className:t.page,children:[u,s.jsxs("div",{className:t.metricGrid,children:[s.jsx(N,{title:d(e("overview.metric.server"),f),value:d(e("status.online"),f),icon:"🖥️",status:"ok",children:s.jsx(s.Fragment,{children:x})}),s.jsx(N,{title:d(e("overview.metric.plugin"),o),value:d(e(T?"status.online":"status.offline"),o),icon:"🔌",subtitle:_?`${_.placeName??"-"} / v${_.pluginVersion??"-"}`:void 0,status:T?"ok":"error"}),s.jsx(N,{title:d(e("overview.metric.agent"),w),value:d((v==null?void 0:v.aiClientName)??e("overview.metric.noAgent"),w),icon:"🤖",subtitle:p>1?`${p} ${e("overview.metric.agent.instancesUnit","instances")}`:void 0,status:v?"ok":"warn"}),s.jsx(N,{title:d(e("overview.metric.sync"),g),value:d(qe(r==null?void 0:r.state,e),g),icon:"🔄",status:Je(r==null?void 0:r.state)})]}),s.jsxs("div",{className:t.card,children:[s.jsx("div",{className:t.cardHeader,children:e("overview.feed.title")}),s.jsx(H,{changes:l})]}),k&&s.jsxs("div",{className:t.card,children:[s.jsx("div",{className:t.cardHeader,children:e("overview.changelog.title")}),s.jsxs("div",{className:t.changelogSummary,children:[s.jsxs("span",{children:[e("overview.changelog.entries","Entries"),": ",C]}),n.scriptsModified>0&&s.jsxs("span",{className:t.changeTag,children:["📝"," ",n.scriptsModified," ",e("overview.changelog.scripts")]}),n.instancesCreated>0&&s.jsxs("span",{className:t.changeTag,children:["🧱"," ",n.instancesCreated," ",e("overview.changelog.instances")]}),n.propertiesChanged>0&&s.jsxs("span",{className:t.changeTag,children:["🎨"," ",n.propertiesChanged," ",e("overview.changelog.properties")]}),n.assetsInserted>0&&s.jsxs("span",{className:t.changeTag,children:["📦"," ",n.assetsInserted," ",e("overview.changelog.assets")]})]})]})]})}export{ts as Component};
1
+ import{j as s,u as R,r as h,d as L,e as F,b as M,D as V}from"./index-Hgv8iCTe.js";import{I as A}from"./InfoLabel-gl5i0JQy.js";import{P as U}from"./PageHeader-BkXyqPrA.js";import{S as z}from"./StatusBadge-BQsRd8hv.js";import{T as O}from"./TooltipText-BEK9VoiS.js";import{G as X}from"./GameChangeDetail-BOp_DXQ9.js";import{u as q,f as J}from"./useLiveUptime-C6MCUOz0.js";const K="_page_amwos_2",Q="_card_amwos_10",W="_cardHeader_amwos_17",Y="_disconnectCard_amwos_28",Z="_disconnectIcon_amwos_36",ee="_disconnectTitle_amwos_41",se="_disconnectMessage_amwos_48",te="_reconnectGuide_amwos_55",ne="_guideStep_amwos_64",ie="_stepNumber_amwos_72",ae="_reconnectIndicator_amwos_88",ce="_reconnectDot_amwos_98",re="_pulse_amwos_1",oe="_disconnectActions_amwos_112",le="_btn_amwos_118",de="_btnSecondary_amwos_134",me="_metricRow_amwos_152",ue="_metricGrid_amwos_158",ve="_metricCard_amwos_164",ge="_metric_ok_amwos_174",_e="_metric_warn_amwos_179",he="_metric_error_amwos_184",pe="_metricHeader_amwos_189",we="_metricIcon_amwos_200",fe="_metricTitle_amwos_204",xe="_metricValue_amwos_208",Ce="_metricSubtitle_amwos_215",je="_guideCard_amwos_225",Ne="_guideTitle_amwos_232",ye="_checklist_amwos_239",Te="_feedEmpty_amwos_263",Se="_feedList_amwos_270",Ie="_feedItem_amwos_278",be="_feedTime_amwos_291",ke="_feedIcon_amwos_298",Me="_feedSummary_amwos_304",De="_feedText_amwos_313",Be="_feedContext_amwos_321",He="_feedItemClickable_amwos_330",Ee="_feedChevron_amwos_338",Pe="_feedDetail_amwos_347",$e="_feedDetailPre_amwos_356",Re="_feedDetailText_amwos_365",Ge="_changelogSummary_amwos_372",Le="_changeTag_amwos_381",Fe="_tierBar_amwos_393",Ve="_tierBarTrack_amwos_399",Ae="_tierBarFillBasic_amwos_407",Ue="_tierBarFillPro_amwos_412",ze="_tierLabels_amwos_417",t={page:K,card:Q,cardHeader:W,disconnectCard:Y,disconnectIcon:Z,disconnectTitle:ee,disconnectMessage:se,reconnectGuide:te,guideStep:ne,stepNumber:ie,reconnectIndicator:ae,reconnectDot:ce,pulse:re,disconnectActions:oe,btn:le,btnSecondary:de,metricRow:me,metricGrid:ue,metricCard:ve,metric_ok:ge,metric_warn:_e,metric_error:he,metricHeader:pe,metricIcon:we,metricTitle:fe,metricValue:xe,metricSubtitle:Ce,guideCard:je,guideTitle:Ne,checklist:ye,feedEmpty:Te,feedList:Se,feedItem:Ie,feedTime:be,feedIcon:ke,feedSummary:Me,feedText:De,feedContext:Be,feedItemClickable:He,feedChevron:Ee,feedDetail:Pe,feedDetailPre:$e,feedDetailText:Re,changelogSummary:Ge,changeTag:Le,tierBar:Fe,tierBarTrack:Ve,tierBarFillBasic:Ae,tierBarFillPro:Ue,tierLabels:ze};function N({title:e,value:i,icon:a,subtitle:c,status:r,children:n}){const l=r?t[`metric_${r}`]:"";return s.jsxs("div",{className:`${t.metricCard} ${l}`,children:[s.jsxs("div",{className:t.metricHeader,children:[a&&s.jsx("span",{className:t.metricIcon,children:a}),s.jsx("span",{className:t.metricTitle,children:e})]}),s.jsx("div",{className:t.metricValue,children:i}),c&&s.jsx("div",{className:t.metricSubtitle,children:c}),n]})}function Oe(e){var a,c;const i=e==null?void 0:e.contextSummary;return(i==null?void 0:i.intent)??((c=(a=i==null?void 0:i.affectedAreas)==null?void 0:a[0])==null?void 0:c.label)??(i==null?void 0:i.testScenario)??null}function H({changes:e}){const{t:i}=R(),[a,c]=h.useState(null);return e.length===0?s.jsx("div",{className:t.feedEmpty,children:i("overview.feed.empty")}):s.jsx("div",{className:t.feedList,children:e.map((r,n)=>{const l=a===n,m=r.raw,u=m&&(m.before!=null||m.after!=null||m.details!=null),p=Oe(m);return s.jsxs("div",{children:[s.jsxs("div",{className:`${t.feedItem} ${u?t.feedItemClickable:""}`,onClick:()=>u&&c(l?null:n),children:[s.jsx("span",{className:t.feedTime,children:r.timestamp}),s.jsx("span",{className:t.feedIcon,children:r.icon}),s.jsxs("span",{className:t.feedText,children:[s.jsx("span",{className:t.feedSummary,children:r.summary}),p&&s.jsx("span",{className:t.feedContext,children:p})]}),u&&s.jsx("span",{className:t.feedChevron,children:l?"▴":"▾"})]}),l&&m&&s.jsx("div",{className:t.feedDetail,children:s.jsx(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(),a=F(),[c,r]=h.useState(null),[n,l]=h.useState(null),[m,u]=h.useState(null),[p,v]=h.useState([]),y=h.useRef(null),T=h.useCallback(async()=>{try{const o=await M.get("/connection-info");r(o)}catch{r(null)}},[]),S=h.useCallback(async()=>{try{const o=await M.get("/api/dashboard/changelog/active");if(u(o),o.recentChanges&&o.recentChanges.length>0){const w=o.recentChanges.map(g=>({timestamp:g.timestamp?G(new Date(g.timestamp)):P(),icon:$(g.category),summary:g.summary,category:g.category,raw:g}));v(w)}}catch{u(null)}},[]),f=h.useCallback(async()=>{try{const o=await M.get("/sync/status");l(o)}catch{l(null)}},[]);return h.useEffect(()=>{e!=="disconnected"?(T(),S(),f()):(r(null),l(null),u(null));const o=new V;y.current=o,o.connect();const w=o.on("game_change",x=>{const _=x,C={timestamp:P(),icon:$(_.category),summary:_.summary,category:_.category};v(k=>{const j=[C,...k];return j.length>E?j.slice(0,E):j}),S()}),g=o.on("sync",x=>{const _=x;l(C=>({...C,state:_.status,..._.placeId?{placeId:_.placeId}:{}}))});return()=>{w(),g(),o.disconnect(),y.current=null}},[e,T,S,f]),{level:e,status:i,connectionInfo:c,syncStatus:n,changeSummary:m,recentChanges:p,tier:a}}function D(e){return e.scriptsModified+e.scriptsCreated+e.instancesCreated+e.instancesDeleted+e.instancesMoved+e.propertiesChanged+e.assetsInserted+(e.lightingChanged?1:0)+(e.terrainChanged?1:0)}function qe(e,i){switch(e){case"syncing":return i("status.syncing","Syncing");case"initializing":return i("status.initializing","Initializing");case"error":return i("status.error","Error");default:return i("status.idle","Idle")}}function Je(e){switch(e){case"syncing":return"ok";case"initializing":return"warn";case"error":return"error";default:return"ok"}}function b(e,i,a,c){return s.jsxs("div",{className:e.metricSubtitle,children:[s.jsx(A,{label:i,tooltip:a}),": ",c]},i)}function d(e,i){return s.jsx(O,{text:i,children:e})}function ts(){var j,B;const{t:e}=R(),{level:i,status:a,connectionInfo:c,syncStatus:r,changeSummary:n,recentChanges:l}=Xe(),m=q(a==null?void 0:a.uptime),u=s.jsx(U,{title:e("page.overview.title","Overview"),description:e("page.overview.description","Check server, plugin, agent, sync, and recent game-change status in one place."),helpTopicId:"overview",helpState:{connectionLevel:i}});if(i==="disconnected")return s.jsxs("div",{className:t.page,children:[u,s.jsxs("div",{className:t.disconnectCard,children:[s.jsx("div",{className:t.disconnectIcon,children:"⚠️"}),s.jsx("h2",{className:t.disconnectTitle,children:e("overview.l0.title")}),s.jsx("p",{className:t.disconnectMessage,children:e("overview.l0.message")}),s.jsxs("div",{className:t.reconnectGuide,children:[s.jsxs("div",{className:t.guideStep,children:[s.jsx("span",{className:t.stepNumber,children:"1"}),s.jsx("span",{children:e("overview.l0.step1")})]}),s.jsxs("div",{className:t.guideStep,children:[s.jsx("span",{className:t.stepNumber,children:"2"}),s.jsx("span",{children:e("overview.l0.step2")})]})]}),s.jsxs("div",{className:t.reconnectIndicator,children:[s.jsx("span",{className:t.reconnectDot}),e("overview.l0.reconnecting")]}),s.jsxs("div",{className:t.disconnectActions,children:[s.jsx("button",{className:t.btn,onClick:()=>window.location.reload(),children:e("overview.l0.reconnectBtn")}),s.jsx("button",{className:t.btnSecondary,onClick:()=>{window.location.hash="#/settings"},children:e("overview.l0.settingsBtn")})]})]})]});const p=(c==null?void 0:c.mcpInstanceCount)??0,v=((j=c==null?void 0:c.mcpInstances)==null?void 0:j.find(I=>!I.isServer&&I.aiClientName))??((B=c==null?void 0:c.mcpInstances)==null?void 0:B.find(I=>!!I.aiClientName))??null,y=(a==null?void 0:a.pluginClients)??[],T=y.length>0,S=(a==null?void 0:a.sessionId)??(c==null?void 0:c.sessionId)??"-",f=e("overview.metric.server.tooltip","MCP server runtime and process status"),o=e("overview.metric.plugin.tooltip","Roblox Studio plugin connection and version status"),w=e("overview.metric.agent.tooltip","Connected AI coding agents and their runtime state"),g=e("overview.metric.sync.tooltip","Current Studio to local sync activity"),x=a?[b(t,e("overview.meta.version","Version"),e("overview.meta.version.tooltip","Installed MCP server version"),`v${a.version}`),b(t,e("overview.meta.session","Session"),e("overview.meta.session.tooltip","Current MCP session identifier"),S),b(t,e("overview.meta.pid","PID"),e("overview.meta.pid.tooltip","Operating system process identifier"),String(a.pid??"-")),b(t,e("overview.meta.uptime","Uptime"),e("overview.meta.uptime.tooltip","Time elapsed since the MCP server started"),J(m??a.uptime))]:[];if(i==="serverOnly")return s.jsxs("div",{className:t.page,children:[u,s.jsxs("div",{className:t.metricRow,children:[s.jsx(N,{title:d(e("overview.metric.server"),f),value:d(e("status.online"),f),icon:"🖥️",status:"ok",children:s.jsxs(s.Fragment,{children:[x,s.jsx(z,{status:"online"})]})}),s.jsx(N,{title:d(e("overview.metric.agent"),w),value:d((v==null?void 0:v.aiClientName)??e("overview.metric.noAgent"),w),icon:"🤖",subtitle:p>1?`${p} ${e("overview.metric.agent.instancesUnit","instances")}`:void 0,status:v?"ok":"warn"})]}),s.jsxs("div",{className:t.guideCard,children:[s.jsx("h3",{className:t.guideTitle,children:e("overview.l1.pluginGuide")}),s.jsxs("ul",{className:t.checklist,children:[s.jsx("li",{children:e("overview.l1.check1")}),s.jsx("li",{children:e("overview.l1.check2")})]})]}),s.jsxs("div",{className:t.card,children:[s.jsx("div",{className:t.cardHeader,children:e("overview.feed.title")}),l.length>0?s.jsx(H,{changes:l}):s.jsx("div",{className:t.feedEmpty,children:e("overview.l1.feedHint")})]}),n&&D(n)>0&&s.jsxs("div",{className:t.card,children:[s.jsx("div",{className:t.cardHeader,children:e("overview.changelog.title")}),s.jsxs("div",{className:t.changelogSummary,children:[s.jsxs("span",{children:[e("overview.changelog.entries","Entries"),": ",D(n)]}),n.scriptsModified>0&&s.jsxs("span",{className:t.changeTag,children:["📝"," ",n.scriptsModified," ",e("overview.changelog.scripts")]}),n.instancesCreated>0&&s.jsxs("span",{className:t.changeTag,children:["🧱"," ",n.instancesCreated," ",e("overview.changelog.instances")]}),n.propertiesChanged>0&&s.jsxs("span",{className:t.changeTag,children:["🎨"," ",n.propertiesChanged," ",e("overview.changelog.properties")]}),n.assetsInserted>0&&s.jsxs("span",{className:t.changeTag,children:["📦"," ",n.assetsInserted," ",e("overview.changelog.assets")]})]})]})]});const _=y[0],C=n?D(n):0,k=!!n&&C>0;return s.jsxs("div",{className:t.page,children:[u,s.jsxs("div",{className:t.metricGrid,children:[s.jsx(N,{title:d(e("overview.metric.server"),f),value:d(e("status.online"),f),icon:"🖥️",status:"ok",children:s.jsx(s.Fragment,{children:x})}),s.jsx(N,{title:d(e("overview.metric.plugin"),o),value:d(e(T?"status.online":"status.offline"),o),icon:"🔌",subtitle:_?`${_.placeName??"-"} / v${_.pluginVersion??"-"}`:void 0,status:T?"ok":"error"}),s.jsx(N,{title:d(e("overview.metric.agent"),w),value:d((v==null?void 0:v.aiClientName)??e("overview.metric.noAgent"),w),icon:"🤖",subtitle:p>1?`${p} ${e("overview.metric.agent.instancesUnit","instances")}`:void 0,status:v?"ok":"warn"}),s.jsx(N,{title:d(e("overview.metric.sync"),g),value:d(qe(r==null?void 0:r.state,e),g),icon:"🔄",status:Je(r==null?void 0:r.state)})]}),s.jsxs("div",{className:t.card,children:[s.jsx("div",{className:t.cardHeader,children:e("overview.feed.title")}),s.jsx(H,{changes:l})]}),k&&s.jsxs("div",{className:t.card,children:[s.jsx("div",{className:t.cardHeader,children:e("overview.changelog.title")}),s.jsxs("div",{className:t.changelogSummary,children:[s.jsxs("span",{children:[e("overview.changelog.entries","Entries"),": ",C]}),n.scriptsModified>0&&s.jsxs("span",{className:t.changeTag,children:["📝"," ",n.scriptsModified," ",e("overview.changelog.scripts")]}),n.instancesCreated>0&&s.jsxs("span",{className:t.changeTag,children:["🧱"," ",n.instancesCreated," ",e("overview.changelog.instances")]}),n.propertiesChanged>0&&s.jsxs("span",{className:t.changeTag,children:["🎨"," ",n.propertiesChanged," ",e("overview.changelog.properties")]}),n.assetsInserted>0&&s.jsxs("span",{className:t.changeTag,children:["📦"," ",n.assetsInserted," ",e("overview.changelog.assets")]})]})]})]})}export{ts as Component};
@@ -1,4 +1,4 @@
1
- import{f as oe,r as u,j as t,u as se,a as ae,X as re,E as ie,h as ce,p as le}from"./index-DchewB5y.js";/**
1
+ import{f as oe,r as u,j as t,u as se,a as ae,X as re,E as ie,h as ce,p as le}from"./index-Hgv8iCTe.js";/**
2
2
  * @license lucide-react v1.8.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -0,0 +1 @@
1
+ import{u as i,r,j as c}from"./index-Hgv8iCTe.js";import{A as n}from"./AiPromptExamples-CJjCcxg8.js";const m=["character","automated-check","selection","game-state"];function y(t){return m.map(a=>({id:a,title:t(`playtest.ai.examples.${a}.title`),request:t(`playtest.ai.examples.${a}.request`)}))}function d(t){const{locale:a,t:e}=i(),s=t.exampleIds.join("|"),o=r.useMemo(()=>{const p=new Set(t.exampleIds);return y(e).filter(l=>p.has(l.id))},[s,e]);return c.jsx(n,{examples:o,resetKey:`${a}|${s}`,labels:{copy:e("playtest.ai.copy","Copy request"),copying:e("playtest.ai.copying","Copying…"),copied:e("playtest.ai.copied","Copied"),copyFailed:e("playtest.ai.copyFailed","Could not copy. Select the request text and copy it manually.")}})}export{d as P};
@@ -1,4 +1,4 @@
1
- import{f as Ee,j as t,X as Et,r as o,b as Ae,u as me,D as Bt,p as Ot,k as Ft,s as Ht,c as Gt,o as qt,a as Ut,e as Kt,d as zt,i as Wt,T as Yt}from"./index-DchewB5y.js";import{T as Jt}from"./TierPromoPanel-C02VRkHz.js";import{P as Qt,a as Xt}from"./PageHeader-CYbeZdtL.js";import{I as Zt}from"./InfoLabel-BGeOUBIl.js";import{C as ea}from"./CurrentPlaceScope-DhPCqaMU.js";import{T as Ze}from"./TooltipText-sb-BSgUg.js";import{C as ot}from"./ConfirmModal-Dz7mVKLZ.js";import{T as ta,C as Ge}from"./Tabs-C7TenrZD.js";import{P as vt}from"./PlaytestAiPromptExamples-flhav1EU.js";import{B as aa}from"./bot-oMwejCZF.js";import{T as ft}from"./trash-2-8V3SCC8q.js";import{C as sa}from"./check-EdHXSSef.js";import"./ConfirmModal.module-DJksQHBd.js";import"./copy-CePVq0VI.js";/**
1
+ import{f as Ee,j as t,X as Et,r as o,b as Ae,u as me,D as Bt,p as Ot,k as Ft,s as Ht,c as Gt,o as qt,a as Ut,e as Kt,d as zt,i as Wt,T as Yt}from"./index-Hgv8iCTe.js";import{T as Jt}from"./TierPromoPanel-nA1RBcJp.js";import{P as Qt,a as Xt}from"./PageHeader-BkXyqPrA.js";import{I as Zt}from"./InfoLabel-gl5i0JQy.js";import{C as ea}from"./CurrentPlaceScope-p_fkZWK9.js";import{T as Ze}from"./TooltipText-BEK9VoiS.js";import{C as ot}from"./ConfirmModal-DaOuVA6n.js";import{T as ta,C as Ge}from"./Tabs-Dy5daI-F.js";import{P as vt}from"./PlaytestAiPromptExamples-Ciyd-GNB.js";import{B as aa}from"./bot-B06rJuWg.js";import{T as ft}from"./trash-2-DMQtyT_y.js";import{C as sa}from"./check-CZ_wdz7l.js";import"./ConfirmModal.module-DJksQHBd.js";import"./AiPromptExamples-CJjCcxg8.js";import"./copy-CGFMtAPH.js";/**
2
2
  * @license lucide-react v1.8.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -124,4 +124,4 @@ return {
124
124
  "$className": "DataModel",
125
125
  "ServerStorage": { "$path": "src/ServerStorage" }
126
126
  }
127
- }`;function Jo(e){const{t:a}=me();return t.jsxs("section",{className:s.deploymentGuide,"aria-label":a("playtest.guide.title"),children:[t.jsxs("header",{className:s.deploymentLifecycle,children:[e.showHeading!==!1&&t.jsx("h2",{children:a("playtest.guide.title")}),t.jsx("p",{children:a("playtest.guide.runtime")}),t.jsx("p",{children:a("playtest.guide.local")}),t.jsx("p",{children:a("playtest.guide.methodIntro")})]}),e.hasManagedAdapterWithoutStudioGuard&&t.jsxs("section",{className:s.deploymentNotice,children:[t.jsx("h3",{children:a("playtest.guide.studioGuardNoticeTitle")}),t.jsx("p",{children:a("playtest.guide.studioGuardNotice")})]}),t.jsxs("section",{className:s.deploymentChecklist,"aria-labelledby":"playtest-publish-checklist-title",children:[t.jsx("h3",{id:"playtest-publish-checklist-title",children:a("playtest.guide.checklistTitle")}),t.jsxs("ul",{children:[t.jsx("li",{children:a("playtest.guide.checklistTarget")}),t.jsx("li",{children:a("playtest.guide.checklistBehavior")})]})]}),t.jsxs("div",{className:s.deploymentScope,children:[t.jsxs("section",{className:s.deploymentLifecycle,children:[t.jsx("h3",{children:a("playtest.guide.excludeTitle")}),t.jsx("p",{children:a("playtest.guide.exclude")})]}),t.jsxs("section",{className:s.deploymentLifecycle,children:[t.jsx("h3",{children:a("playtest.guide.conditionalDataTitle")}),t.jsx("p",{children:a("playtest.guide.checklistData")})]})]}),t.jsxs("section",{className:s.deploymentLifecycle,children:[t.jsx("h3",{children:a("playtest.guide.afterPublishTitle")}),t.jsx("p",{children:a("playtest.guide.final")})]}),t.jsxs("details",{className:s.deploymentDetails,children:[t.jsx("summary",{children:a("playtest.guide.studioTitle")}),t.jsx("p",{children:a("playtest.guide.include")}),t.jsx("p",{children:a("playtest.guide.studio")})]}),t.jsxs("details",{className:s.deploymentDetails,children:[t.jsx("summary",{children:a("playtest.guide.rojoTitle")}),t.jsx("p",{children:a("playtest.guide.rojo")}),t.jsx("pre",{children:Yo}),t.jsx("p",{children:a("playtest.guide.rojoExample")})]}),t.jsxs("details",{className:s.deploymentDetails,children:[t.jsx("summary",{children:a("playtest.guide.dataTitle")}),t.jsx("p",{children:a("playtest.guide.data")})]}),t.jsx("p",{className:s.deploymentDescription,children:a("playtest.guide.description")})]})}function Qo(e){return e.studioState==="running"?"Running":e.studioState==="paused"?"Paused":"Edit"}function Xo(e,a){const i=((e==null?void 0:e.pluginClients)??[]).filter(d=>d.connectionState==="connected");let l;if(a!==null){const d=i.filter(u=>u.placeId===a);l=d.length===1?d[0]:void 0}else l=Ht(i,(e==null?void 0:e.studioRoutingMode)??"recentPriority",(e==null?void 0:e.pinnedTargetClientId)??null)[0];return l?{state:Qo(l),targetClientId:l.clientId,...l.studioStateUpdatedAt!==void 0?{updatedAt:l.studioStateUpdatedAt}:{},...l.playtestMode!==void 0?{mode:l.playtestMode}:{}}:{state:"Edit",targetClientId:null}}function yc(){var r,y,j,g,w;const{t:e}=me(),a=Gt(),i=qt(),{trackEvent:l}=Ut(),{tier:d,loading:u}=Kt(),{level:c,status:b}=zt(),v=!u&&d==="basic",[_,R]=o.useState(null),x=Da({enabled:!v,placeId:_}),S=Xo(b,_),f=go({enabled:!u&&c==="studioConnected",canMutate:!v,placeId:_,studioSnapshot:S}),[E,m]=o.useState(mo),[D,M]=o.useState(!1),[I,P]=o.useState(!1),[k,O]=o.useState(!1),T=o.useRef(null),[L,ee]=o.useState(!1),{show:H}=Wt(),[A,G]=o.useState(null),[U,ae]=o.useState(!1),[de,ne]=o.useState(!1);o.useEffect(()=>{const C=new URLSearchParams(a.search);if(C.get("add")!=="value")return;m("live"),P(!0),C.delete("add");const q=C.toString();i(`${a.pathname}${q?`?${q}`:""}${a.hash}`,{replace:!0})},[a.hash,a.pathname,a.search,i]);const z=c==="studioConnected",Y=z?f.profile?f.studioState==="Edit"?e("playtest.values.playRequired","Start Play or Run in Studio to change test values."):v?e("playtest.controls.proRequired","Real-time value editing and Reset all are available with Pro."):e("playtest.controls.connectingDescription","Preparing runtime controls for the selected profile…"):e("playtest.controls.profileRequired","Select or create a test profile to change values."):e("playtest.controls.studioRequired","Connect Roblox Studio and WEPPY Plugin to change test values."),K=z?f.studioState:"Disconnected",$=o.useRef(null),{history:Q,historyLoadState:Ne,historyError:X,selectedReport:he,loading:V,detailLoading:pe,detailError:Z}=x,se=v?Ta(e):null,ve=((r=se==null?void 0:se.history[0])==null?void 0:r.recordId)??null,oe=(se==null?void 0:se.history)??Q,be=se&&A===ve?se.report:he,xe=v?!1:V,je=oe.find(C=>C.recordId===A),Pe=(C,q)=>{$.current=q,G(C),!v&&x.loadReport(C)},fe=o.useCallback(()=>{G(null),x.clearSelectedReport()},[x.clearSelectedReport]),we=async()=>{ne(!0);try{await x.clearHistory(),H(e("toast.clearSuccess","Cleared successfully"),"success"),ae(!1),G(null)}catch{H(e("toast.clearFailed","Failed to clear data"),"error")}finally{ne(!1)}};return t.jsxs("div",{className:s.page,children:[t.jsx(Qt,{title:e("page.playtest.title","Playtest"),description:e("page.playtest.description","Review automated playtest runs, saved reports, and result history."),helpTopicId:"playtest",helpState:{tier:d},actions:t.jsx(Xt,{ref:T,type:"button",variant:"secondary",size:"sm",onClick:()=>O(!0),children:e("playtest.guide.open","Before publishing")})}),!u&&t.jsx(ea,{surface:"playtest",selectable:!0,selectedPlaceId:_,onSelectedPlaceIdChange:C=>{R(C),G(null),x.clearSelectedReport()}}),!u&&t.jsxs(t.Fragment,{children:[t.jsx(bo,{value:E,onChange:C=>{m(C),ho(C)}}),t.jsx(_o,{lease:f.lease,profileName:(y=f.profile)==null?void 0:y.name,studioState:K,studioMode:S.mode}),v&&t.jsx(Jt,{title:e("playtest.upgrade.title","Real-time Playtest controls are available with Pro"),description:e("playtest.upgrade.description","Basic includes test profiles and live runtime observation. Upgrade when you need to change values during Play."),benefits:[e("playtest.upgrade.benefit1","Change test values while Studio Play is running"),e("playtest.upgrade.benefit2","Reset every override to its original value"),e("playtest.upgrade.benefit3","Review actual saved automated test results instead of sample data")],upgradeLabel:e("tier.upgrade","View Pro"),upgradeHref:Yt.playtest}),f.error&&t.jsx("div",{className:s.inlineError,role:"alert",children:f.error}),E==="live"&&t.jsx(Oo,{live:f,inactiveReason:Y,onManageValues:()=>P(!0),onNewProfile:()=>{ee(!1),M(!0)},onEditProfile:()=>{ee(!0),M(!0)},directAddDisabledReason:z?void 0:e("playtest.controls.studioRequired","Connect Roblox Studio and WEPPY Plugin to change test values.")})]}),E==="results"&&t.jsxs("div",{className:s.card,role:"tabpanel","aria-label":e("playtest.view.testResults","Automated Test Results"),children:[t.jsxs("div",{className:s.cardHeader,children:[t.jsx(Zt,{label:e("playtest.history.title","Test History"),tooltip:e("playtest.history.title.tooltip","Recorded automated playtest runs for this project.")}),v?t.jsx(Ze,{text:e("playtest.sample.clearDisabled","Available with Pro for live playtest history."),children:t.jsx("span",{children:t.jsx("button",{className:s.clearButton,disabled:!0,children:e("common.clear","Clear")})})}):t.jsx("button",{className:s.clearButton,onClick:()=>{l("dashboard_click_event",{click_target:"playtest_clear_history",page:"playtest"}),ae(!0)},children:e("common.clear","Clear")})]}),(v||!xe&&Ne==="ready"&&oe.length===0)&&t.jsx(Vt,{kind:"no-results",isBasic:v}),!v&&Ne==="error"&&oe.length===0&&t.jsxs("div",{className:s.inlineError,role:"alert",children:[t.jsx("span",{children:X??e("playtest.emptyResults.loadFailed","Could not load test results.")}),t.jsx("button",{type:"button",className:s.secondaryAction,onClick:()=>void x.retryHistory(),children:e("common.retry","Try again")})]}),xe?t.jsx("div",{className:s.emptyState,children:e("common.loading","Loading...")}):oe.length===0?null:t.jsx(lo,{entries:oe,onSelect:Pe,selectedRecordId:A??void 0})]}),t.jsx(Ge,{open:k,ariaLabel:e("playtest.guide.title","Publishing your game after playtesting"),onClose:()=>O(!1),returnFocusTo:T.current,children:t.jsxs("div",{className:s.detailShell,children:[t.jsx(qe,{title:e("playtest.guide.title","Publishing your game after playtesting"),description:e("playtest.guide.dialogDescription","Review what remains after testing and what to check before publishing."),closeLabel:e("common.close","Close"),onRequestClose:()=>O(!1)}),t.jsx("div",{className:s.detailBody,children:t.jsx(Jo,{showHeading:!1,hasManagedAdapterWithoutStudioGuard:((j=f.releaseGuidance)==null?void 0:j.hasManagedAdapterWithoutStudioGuard)===!0})})]})}),t.jsx(Ge,{open:A!==null,ariaLabel:e("playtest.detail.dialogLabel","Playtest report detail"),onClose:fe,returnFocusTo:$.current,testId:"playtest-detail-popup-layer",children:t.jsxs("div",{className:s.detailShell,children:[t.jsx(qe,{title:e("playtest.report.title","Selected Report"),description:je==null?void 0:je.testName,closeLabel:e("common.close","Close"),onRequestClose:fe}),t.jsx("div",{className:s.detailBody,children:pe?t.jsx("div",{className:s.detailState,role:"status",children:e("playtest.detail.loading","Loading report...")}):Z?t.jsxs("div",{className:s.detailState,role:"alert",children:[t.jsx("div",{className:s.detailErrorTitle,children:e("playtest.detail.errorTitle","Report unavailable")}),t.jsx("div",{className:s.detailErrorMessage,children:Z}),t.jsx("button",{type:"button",className:s.detailRetryButton,onClick:()=>void x.retryReport(),children:e("common.retry","Retry")})]}):be?t.jsx(po,{report:be}):t.jsx("div",{className:s.detailState,role:"status",children:e("playtest.detail.loading","Loading report...")})})]})}),!u&&t.jsxs(t.Fragment,{children:[!v&&t.jsx(ot,{open:U,title:e("playtest.clear.title","Clear test history?"),message:e("playtest.clear.message","This permanently removes the stored playtest reports for the current place."),cancelLabel:e("common.cancel","Cancel"),confirmLabel:e("common.clear","Clear"),loading:de,onCancel:()=>!de&&ae(!1),onConfirm:we}),t.jsx(qo,{open:D,onClose:()=>M(!1),profile:L?f.profile:null,onCreate:f.createProfile,onSave:f.saveProfile,onDelete:async(C,q)=>{const ie=await f.deleteProfile(C,q);H(ie.refreshFailed?e("playtest.profile.deleteRefreshFailed","Profile deleted. Reload the profile list to confirm the latest state."):e("playtest.profile.deleteSuccess","Profile deleted."),ie.refreshFailed?"warning":"success")},deleteDisabledReason:((g=f.lease)==null?void 0:g.profileId)===((w=f.profile)==null?void 0:w.id)?e("playtest.profile.deleteActive","This profile is in use. Stop Play or Run in Studio before deleting it."):void 0,onResolveSelection:f.resolveSelection,onResolveSelectionCandidates:f.resolveSelectionCandidates}),t.jsx(Wo,{open:I,profile:f.profile,catalog:f.catalog,activeLease:!!f.lease,onClose:()=>P(!1),onSave:f.saveProfile,onCreateProfile:f.createProfile,onResolveSelectionCandidates:f.resolveSelectionCandidates})]})]})}export{yc as Component};
127
+ }`;function Jo(e){const{t:a}=me();return t.jsxs("section",{className:s.deploymentGuide,"aria-label":a("playtest.guide.title"),children:[t.jsxs("header",{className:s.deploymentLifecycle,children:[e.showHeading!==!1&&t.jsx("h2",{children:a("playtest.guide.title")}),t.jsx("p",{children:a("playtest.guide.runtime")}),t.jsx("p",{children:a("playtest.guide.local")}),t.jsx("p",{children:a("playtest.guide.methodIntro")})]}),e.hasManagedAdapterWithoutStudioGuard&&t.jsxs("section",{className:s.deploymentNotice,children:[t.jsx("h3",{children:a("playtest.guide.studioGuardNoticeTitle")}),t.jsx("p",{children:a("playtest.guide.studioGuardNotice")})]}),t.jsxs("section",{className:s.deploymentChecklist,"aria-labelledby":"playtest-publish-checklist-title",children:[t.jsx("h3",{id:"playtest-publish-checklist-title",children:a("playtest.guide.checklistTitle")}),t.jsxs("ul",{children:[t.jsx("li",{children:a("playtest.guide.checklistTarget")}),t.jsx("li",{children:a("playtest.guide.checklistBehavior")})]})]}),t.jsxs("div",{className:s.deploymentScope,children:[t.jsxs("section",{className:s.deploymentLifecycle,children:[t.jsx("h3",{children:a("playtest.guide.excludeTitle")}),t.jsx("p",{children:a("playtest.guide.exclude")})]}),t.jsxs("section",{className:s.deploymentLifecycle,children:[t.jsx("h3",{children:a("playtest.guide.conditionalDataTitle")}),t.jsx("p",{children:a("playtest.guide.checklistData")})]})]}),t.jsxs("section",{className:s.deploymentLifecycle,children:[t.jsx("h3",{children:a("playtest.guide.afterPublishTitle")}),t.jsx("p",{children:a("playtest.guide.final")})]}),t.jsxs("details",{className:s.deploymentDetails,children:[t.jsx("summary",{children:a("playtest.guide.studioTitle")}),t.jsx("p",{children:a("playtest.guide.include")}),t.jsx("p",{children:a("playtest.guide.studio")})]}),t.jsxs("details",{className:s.deploymentDetails,children:[t.jsx("summary",{children:a("playtest.guide.rojoTitle")}),t.jsx("p",{children:a("playtest.guide.rojo")}),t.jsx("pre",{children:Yo}),t.jsx("p",{children:a("playtest.guide.rojoExample")})]}),t.jsxs("details",{className:s.deploymentDetails,children:[t.jsx("summary",{children:a("playtest.guide.dataTitle")}),t.jsx("p",{children:a("playtest.guide.data")})]}),t.jsx("p",{className:s.deploymentDescription,children:a("playtest.guide.description")})]})}function Qo(e){return e.studioState==="running"?"Running":e.studioState==="paused"?"Paused":"Edit"}function Xo(e,a){const i=((e==null?void 0:e.pluginClients)??[]).filter(d=>d.connectionState==="connected");let l;if(a!==null){const d=i.filter(u=>u.placeId===a);l=d.length===1?d[0]:void 0}else l=Ht(i,(e==null?void 0:e.studioRoutingMode)??"recentPriority",(e==null?void 0:e.pinnedTargetClientId)??null)[0];return l?{state:Qo(l),targetClientId:l.clientId,...l.studioStateUpdatedAt!==void 0?{updatedAt:l.studioStateUpdatedAt}:{},...l.playtestMode!==void 0?{mode:l.playtestMode}:{}}:{state:"Edit",targetClientId:null}}function mc(){var r,y,j,g,w;const{t:e}=me(),a=Gt(),i=qt(),{trackEvent:l}=Ut(),{tier:d,loading:u}=Kt(),{level:c,status:b}=zt(),v=!u&&d==="basic",[_,R]=o.useState(null),x=Da({enabled:!v,placeId:_}),S=Xo(b,_),f=go({enabled:!u&&c==="studioConnected",canMutate:!v,placeId:_,studioSnapshot:S}),[E,m]=o.useState(mo),[D,M]=o.useState(!1),[I,P]=o.useState(!1),[k,O]=o.useState(!1),T=o.useRef(null),[L,ee]=o.useState(!1),{show:H}=Wt(),[A,G]=o.useState(null),[U,ae]=o.useState(!1),[de,ne]=o.useState(!1);o.useEffect(()=>{const C=new URLSearchParams(a.search);if(C.get("add")!=="value")return;m("live"),P(!0),C.delete("add");const q=C.toString();i(`${a.pathname}${q?`?${q}`:""}${a.hash}`,{replace:!0})},[a.hash,a.pathname,a.search,i]);const z=c==="studioConnected",Y=z?f.profile?f.studioState==="Edit"?e("playtest.values.playRequired","Start Play or Run in Studio to change test values."):v?e("playtest.controls.proRequired","Real-time value editing and Reset all are available with Pro."):e("playtest.controls.connectingDescription","Preparing runtime controls for the selected profile…"):e("playtest.controls.profileRequired","Select or create a test profile to change values."):e("playtest.controls.studioRequired","Connect Roblox Studio and WEPPY Plugin to change test values."),K=z?f.studioState:"Disconnected",$=o.useRef(null),{history:Q,historyLoadState:Ne,historyError:X,selectedReport:he,loading:V,detailLoading:pe,detailError:Z}=x,se=v?Ta(e):null,ve=((r=se==null?void 0:se.history[0])==null?void 0:r.recordId)??null,oe=(se==null?void 0:se.history)??Q,be=se&&A===ve?se.report:he,xe=v?!1:V,je=oe.find(C=>C.recordId===A),Pe=(C,q)=>{$.current=q,G(C),!v&&x.loadReport(C)},fe=o.useCallback(()=>{G(null),x.clearSelectedReport()},[x.clearSelectedReport]),we=async()=>{ne(!0);try{await x.clearHistory(),H(e("toast.clearSuccess","Cleared successfully"),"success"),ae(!1),G(null)}catch{H(e("toast.clearFailed","Failed to clear data"),"error")}finally{ne(!1)}};return t.jsxs("div",{className:s.page,children:[t.jsx(Qt,{title:e("page.playtest.title","Playtest"),description:e("page.playtest.description","Review automated playtest runs, saved reports, and result history."),helpTopicId:"playtest",helpState:{tier:d},actions:t.jsx(Xt,{ref:T,type:"button",variant:"secondary",size:"sm",onClick:()=>O(!0),children:e("playtest.guide.open","Before publishing")})}),!u&&t.jsx(ea,{surface:"playtest",selectable:!0,selectedPlaceId:_,onSelectedPlaceIdChange:C=>{R(C),G(null),x.clearSelectedReport()}}),!u&&t.jsxs(t.Fragment,{children:[t.jsx(bo,{value:E,onChange:C=>{m(C),ho(C)}}),t.jsx(_o,{lease:f.lease,profileName:(y=f.profile)==null?void 0:y.name,studioState:K,studioMode:S.mode}),v&&t.jsx(Jt,{title:e("playtest.upgrade.title","Real-time Playtest controls are available with Pro"),description:e("playtest.upgrade.description","Basic includes test profiles and live runtime observation. Upgrade when you need to change values during Play."),benefits:[e("playtest.upgrade.benefit1","Change test values while Studio Play is running"),e("playtest.upgrade.benefit2","Reset every override to its original value"),e("playtest.upgrade.benefit3","Review actual saved automated test results instead of sample data")],upgradeLabel:e("tier.upgrade","View Pro"),upgradeHref:Yt.playtest}),f.error&&t.jsx("div",{className:s.inlineError,role:"alert",children:f.error}),E==="live"&&t.jsx(Oo,{live:f,inactiveReason:Y,onManageValues:()=>P(!0),onNewProfile:()=>{ee(!1),M(!0)},onEditProfile:()=>{ee(!0),M(!0)},directAddDisabledReason:z?void 0:e("playtest.controls.studioRequired","Connect Roblox Studio and WEPPY Plugin to change test values.")})]}),E==="results"&&t.jsxs("div",{className:s.card,role:"tabpanel","aria-label":e("playtest.view.testResults","Automated Test Results"),children:[t.jsxs("div",{className:s.cardHeader,children:[t.jsx(Zt,{label:e("playtest.history.title","Test History"),tooltip:e("playtest.history.title.tooltip","Recorded automated playtest runs for this project.")}),v?t.jsx(Ze,{text:e("playtest.sample.clearDisabled","Available with Pro for live playtest history."),children:t.jsx("span",{children:t.jsx("button",{className:s.clearButton,disabled:!0,children:e("common.clear","Clear")})})}):t.jsx("button",{className:s.clearButton,onClick:()=>{l("dashboard_click_event",{click_target:"playtest_clear_history",page:"playtest"}),ae(!0)},children:e("common.clear","Clear")})]}),(v||!xe&&Ne==="ready"&&oe.length===0)&&t.jsx(Vt,{kind:"no-results",isBasic:v}),!v&&Ne==="error"&&oe.length===0&&t.jsxs("div",{className:s.inlineError,role:"alert",children:[t.jsx("span",{children:X??e("playtest.emptyResults.loadFailed","Could not load test results.")}),t.jsx("button",{type:"button",className:s.secondaryAction,onClick:()=>void x.retryHistory(),children:e("common.retry","Try again")})]}),xe?t.jsx("div",{className:s.emptyState,children:e("common.loading","Loading...")}):oe.length===0?null:t.jsx(lo,{entries:oe,onSelect:Pe,selectedRecordId:A??void 0})]}),t.jsx(Ge,{open:k,ariaLabel:e("playtest.guide.title","Publishing your game after playtesting"),onClose:()=>O(!1),returnFocusTo:T.current,children:t.jsxs("div",{className:s.detailShell,children:[t.jsx(qe,{title:e("playtest.guide.title","Publishing your game after playtesting"),description:e("playtest.guide.dialogDescription","Review what remains after testing and what to check before publishing."),closeLabel:e("common.close","Close"),onRequestClose:()=>O(!1)}),t.jsx("div",{className:s.detailBody,children:t.jsx(Jo,{showHeading:!1,hasManagedAdapterWithoutStudioGuard:((j=f.releaseGuidance)==null?void 0:j.hasManagedAdapterWithoutStudioGuard)===!0})})]})}),t.jsx(Ge,{open:A!==null,ariaLabel:e("playtest.detail.dialogLabel","Playtest report detail"),onClose:fe,returnFocusTo:$.current,testId:"playtest-detail-popup-layer",children:t.jsxs("div",{className:s.detailShell,children:[t.jsx(qe,{title:e("playtest.report.title","Selected Report"),description:je==null?void 0:je.testName,closeLabel:e("common.close","Close"),onRequestClose:fe}),t.jsx("div",{className:s.detailBody,children:pe?t.jsx("div",{className:s.detailState,role:"status",children:e("playtest.detail.loading","Loading report...")}):Z?t.jsxs("div",{className:s.detailState,role:"alert",children:[t.jsx("div",{className:s.detailErrorTitle,children:e("playtest.detail.errorTitle","Report unavailable")}),t.jsx("div",{className:s.detailErrorMessage,children:Z}),t.jsx("button",{type:"button",className:s.detailRetryButton,onClick:()=>void x.retryReport(),children:e("common.retry","Retry")})]}):be?t.jsx(po,{report:be}):t.jsx("div",{className:s.detailState,role:"status",children:e("playtest.detail.loading","Loading report...")})})]})}),!u&&t.jsxs(t.Fragment,{children:[!v&&t.jsx(ot,{open:U,title:e("playtest.clear.title","Clear test history?"),message:e("playtest.clear.message","This permanently removes the stored playtest reports for the current place."),cancelLabel:e("common.cancel","Cancel"),confirmLabel:e("common.clear","Clear"),loading:de,onCancel:()=>!de&&ae(!1),onConfirm:we}),t.jsx(qo,{open:D,onClose:()=>M(!1),profile:L?f.profile:null,onCreate:f.createProfile,onSave:f.saveProfile,onDelete:async(C,q)=>{const ie=await f.deleteProfile(C,q);H(ie.refreshFailed?e("playtest.profile.deleteRefreshFailed","Profile deleted. Reload the profile list to confirm the latest state."):e("playtest.profile.deleteSuccess","Profile deleted."),ie.refreshFailed?"warning":"success")},deleteDisabledReason:((g=f.lease)==null?void 0:g.profileId)===((w=f.profile)==null?void 0:w.id)?e("playtest.profile.deleteActive","This profile is in use. Stop Play or Run in Studio before deleting it."):void 0,onResolveSelection:f.resolveSelection,onResolveSelectionCandidates:f.resolveSelectionCandidates}),t.jsx(Wo,{open:I,profile:f.profile,catalog:f.catalog,activeLease:!!f.lease,onClose:()=>P(!1),onSave:f.saveProfile,onCreateProfile:f.createProfile,onResolveSelectionCandidates:f.resolveSelectionCandidates})]})]})}export{mc as Component};