@weppy/roblox-mcp 2.14.6 → 2.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dashboard/dist/assets/{AssetsPage-DfB3E1vb.js → AssetsPage-D3-InAlf.js} +1 -1
  3. package/dashboard/dist/assets/{ChangelogDetailPage-C-VVfjbe.js → ChangelogDetailPage-fmLGEZVO.js} +1 -1
  4. package/dashboard/dist/assets/{ChangelogPage-CkSIdLom.js → ChangelogPage-6KtWInS5.js} +1 -1
  5. package/dashboard/dist/assets/{ConfirmModal-BXbkJq3w.js → ConfirmModal-DJp4ax33.js} +1 -1
  6. package/dashboard/dist/assets/ConnectionPage-D375gmxK.js +11 -0
  7. package/dashboard/dist/assets/{ControlsPage-CBnZkDGD.js → ControlsPage-C7zSLjWc.js} +1 -1
  8. package/dashboard/dist/assets/{CurrentPlaceScope-DJheb09C.js → CurrentPlaceScope-DrtUw6py.js} +1 -1
  9. package/dashboard/dist/assets/{GameChangeDetail-3hQlAqDP.js → GameChangeDetail-Bd5Hg2ZD.js} +1 -1
  10. package/dashboard/dist/assets/{InfoLabel-Cc4MKAYc.js → InfoLabel-HLPMIIL4.js} +1 -1
  11. package/dashboard/dist/assets/{OverviewPage-lps48EeB.js → OverviewPage-Bmem2hyc.js} +1 -1
  12. package/dashboard/dist/assets/{PageHeader-DezmLDg1.js → PageHeader-Cvi0LO4r.js} +1 -1
  13. package/dashboard/dist/assets/{PlaytestPage-N2blmofL.js → PlaytestPage-ChFkixWj.js} +1 -1
  14. package/dashboard/dist/assets/{SettingsPage-D1Et0FOx.js → SettingsPage-v3EWZSAn.js} +1 -1
  15. package/dashboard/dist/assets/{StatusBadge-C3ARQLqC.js → StatusBadge-Cf1Ncow3.js} +1 -1
  16. package/dashboard/dist/assets/{SyncPage-DXgj8uBq.js → SyncPage-BG7u00IT.js} +1 -1
  17. package/dashboard/dist/assets/{Tabs-iku37C2G.js → Tabs-2QEkInbt.js} +1 -1
  18. package/dashboard/dist/assets/{ToolsPage-Cpz4X8R_.js → ToolsPage-DbtQxCAM.js} +1 -1
  19. package/dashboard/dist/assets/{TooltipText-CMx5IM6p.js → TooltipText-1fJvqtMt.js} +1 -1
  20. package/dashboard/dist/assets/{UiPrimitive-ojecpNs1.js → UiPrimitive-CsV5QE01.js} +1 -1
  21. package/dashboard/dist/assets/{UiStudioPage-htI6Z7xJ.js → UiStudioPage-ZLA3xIIN.js} +1 -1
  22. package/dashboard/dist/assets/{WhatsNewPage-DAQ11-Xx.js → WhatsNewPage-S4qEx4iN.js} +1 -1
  23. package/dashboard/dist/assets/{copy-BCrOOq8E.js → copy-d0x3Roiq.js} +1 -1
  24. package/dashboard/dist/assets/{index-B1MZBjK4.js → index-C_exRd2o.js} +67 -35
  25. package/dashboard/dist/assets/{sample-requests-DXD3uKZy.js → sample-requests-BRAniRWZ.js} +1 -1
  26. package/dashboard/dist/assets/{useLiveUptime-fm3oNIW5.js → useLiveUptime-D0TQTjV7.js} +1 -1
  27. package/dashboard/dist/assets/{useSettings-BGSD8gFB.js → useSettings-DlZqZGnP.js} +1 -1
  28. package/dashboard/dist/index.html +1 -1
  29. package/dist/index.js +248 -243
  30. package/package.json +1 -1
  31. package/roblox-plugin/WeppyRobloxMCP.rbxm +0 -0
  32. package/dashboard/dist/assets/ConnectionPage-ECCqDYiG.js +0 -11
package/CHANGELOG.md CHANGED
@@ -40,6 +40,27 @@ All notable changes to this project will be documented in this file.
40
40
 
41
41
 
42
42
 
43
+
44
+
45
+ ## [2.15.0] - 2026-08-27
46
+
47
+ ### Features
48
+
49
+ - **Keep Studio connected when an Agent session ends** — The Studio Plugin connection now belongs to a shared WEPPY Bridge instead of an individual AI Agent session. Closing or switching an Agent no longer shuts down that shared connection, reducing unnecessary reconnect waits and request retries. No settings change is required.
50
+ - **See each connection boundary in Dashboard** — The Connection page now shows AI Agents, their per-session MCP Adapters, the shared WEPPY Bridge, and Studio Targets as separate connected roles, with the current state of each connection.
51
+
52
+ ### Bug Fixes
53
+
54
+ - **Resume a paused Playtest after delayed Studio status updates** — A stale running observation no longer overwrites the requested paused state before the resume command is processed.
55
+ - **Keep required responsive checks in UI Studio reviews** — UI Studio now preserves a design's required screen-size review setting through its check summary, so unfinished required coverage remains visible instead of being treated as optional.
56
+ - **Use terrain fill materials without misleading warnings** — Block, ball, cylinder, and wedge terrain fills now recognize the selected material as a valid option instead of reporting it as unused.
57
+ - **Resolve animation controls from Model paths** — Animation track requests now find a Model's Humanoid or AnimationController, while direct controller paths continue to work.
58
+ - **Explain Studio asset upload failures more clearly** — When Roblox Studio cannot run an asset upload, WEPPY now returns the failure stage and actionable guidance instead of an ambiguous error.
59
+
60
+ ### Stability
61
+
62
+ - **Recover the shared Studio connection after a Bridge failure** — An active Agent automatically restores an unexpectedly stopped WEPPY Bridge and waits for the Studio Plugin to reconnect before handling the next request. A change command whose completion cannot be confirmed is not repeated automatically, preventing the same change from being applied twice.
63
+ - **Coordinate multiple Agent sessions through one verified Bridge** — Concurrent Agents now discover and share the same authenticated local runtime instead of competing for the Studio connection. Startup, shutdown, and stale runtime recovery use the same ownership checks on macOS and Windows.
43
64
 
44
65
  ## [2.14.6] - 2026-08-25
45
66
 
@@ -1,4 +1,4 @@
1
- import{i as oe,a as O,o as we,u as me,j as s,P as Ns,I as As,r as c,F as Is,p as Ps,R as hs,X as Ge,E as ks,q as ms,g as Rs,e as $s,h as Ls}from"./index-B1MZBjK4.js";import{C as xs}from"./ConfirmModal-BXbkJq3w.js";import{D as Xe,a as Bs,P as Us}from"./PageHeader-DezmLDg1.js";import{T as Z}from"./TooltipText-CMx5IM6p.js";import{B as De,C as Ts}from"./UiPrimitive-ojecpNs1.js";import{C as gs}from"./copy-BCrOOq8E.js";import"./ConfirmModal.module-DJksQHBd.js";/**
1
+ import{i as oe,a as O,o as we,u as me,j as s,P as Ns,I as As,r as c,F as Is,p as Ps,R as hs,X as Ge,E as ks,q as ms,g as Rs,e as $s,h as Ls}from"./index-C_exRd2o.js";import{C as xs}from"./ConfirmModal-DJp4ax33.js";import{D as Xe,a as Bs,P as Us}from"./PageHeader-Cvi0LO4r.js";import{T as Z}from"./TooltipText-1fJvqtMt.js";import{B as De,C as Ts}from"./UiPrimitive-CsV5QE01.js";import{C as gs}from"./copy-d0x3Roiq.js";import"./ConfirmModal.module-DJksQHBd.js";/**
2
2
  * @license lucide-react v1.8.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{r as c,a as O,u as P,b as U,c as H,d as q,j as e}from"./index-B1MZBjK4.js";import{I as W}from"./InfoLabel-Cc4MKAYc.js";import{G as Y}from"./GameChangeDetail-3hQlAqDP.js";import{T as u}from"./TooltipText-CMx5IM6p.js";import{B as z}from"./UiPrimitive-ojecpNs1.js";function J(t){const s={scriptsModified:0,scriptsCreated:0,instancesCreated:0,instancesDeleted:0,instancesMoved:0,propertiesChanged:0,lightingChanged:!1,terrainChanged:!1,assetsInserted:0};for(const r of t)switch(r.category){case"script":r.changeType==="create"?s.scriptsCreated++:s.scriptsModified++;break;case"instance":r.changeType==="create"?s.instancesCreated++:r.changeType==="delete"?s.instancesDeleted++:r.changeType==="move"&&s.instancesMoved++;break;case"property":s.propertiesChanged++;break;case"lighting":s.lightingChanged=!0;break;case"terrain":s.terrainChanged=!0;break;case"asset":s.assetsInserted++;break}return s}function Q(t){if(typeof t=="number")return{placeId:String(t)}}function X(t,s){const[r,p]=c.useState(""),[L,a]=c.useState(""),[h,w]=c.useState(),[y,B]=c.useState("completed"),[$,M]=c.useState([]),[v,R]=c.useState([]),[A,G]=c.useState([]),[K,V]=c.useState(),[S,C]=c.useState(),[b,N]=c.useState(),[T,k]=c.useState({scriptsModified:0,scriptsCreated:0,instancesCreated:0,instancesDeleted:0,instancesMoved:0,propertiesChanged:0,lightingChanged:!1,terrainChanged:!1,assetsInserted:0}),[I,x]=c.useState(!0),[E,f]=c.useState(null),g=c.useCallback(async()=>{if(t){x(!0),f(null);try{const m=Q(s),[d,_]=await Promise.all([m?O.get(`/api/dashboard/changelog/${t}`,m):O.get(`/api/dashboard/changelog/${t}`),m?O.get(`/api/dashboard/changelog/${t}/changes`,m):O.get(`/api/dashboard/changelog/${t}/changes`)]);p(d.entryId),a(d.startTime),w(d.endTime),B(d.status),M(d.entries),R(d.failures),V(d.contextSummary),C(d.replayMetadata),N(d.verificationSummary),G(_.changes),k(J(_.changes))}catch(m){f(m instanceof Error?m.message:"Failed to load changelog detail")}finally{x(!1)}}},[t,s]);return c.useEffect(()=>{g()},[g]),{entryId:r,startTime:L,endTime:h,status:y,entries:$,failures:v,changes:A,changeSummary:T,contextSummary:K,replayMetadata:S,verificationSummary:b,loading:I,error:E,refresh:g}}const Z={script:"📝",instance:"🧱",property:"🎨",lighting:"🌅",terrain:"⛰️",asset:"📦"};function ee(t){return Z[t]??"❓"}const te="_page_11hjw_2",ne="_header_11hjw_10",ae="_backLink_11hjw_16",se="_headerTitle_11hjw_29",ie="_headerTime_11hjw_37",ce="_statusActive_11hjw_44",re="_statusCompleted_11hjw_49",oe="_section_11hjw_54",le="_sectionTitle_11hjw_61",de="_summaryGrid_11hjw_74",me="_summaryCard_11hjw_80",he="_summaryCardActive_11hjw_94",ge="_summaryIcon_11hjw_99",ue="_summaryCount_11hjw_105",pe="_summaryLabel_11hjw_112",ye="_contextGrid_11hjw_121",xe="_contextRow_11hjw_127",fe="_contextKey_11hjw_133",_e="_contextValue_11hjw_141",je="_timelineFilter_11hjw_149",we="_filterLabel_11hjw_157",ve="_filterSelect_11hjw_163",Se="_ownershipToggle_11hjw_173",Ce="_timeline_11hjw_149",be="_timelineEntry_11hjw_201",Ne="_timelineTime_11hjw_218",Te="_timelineIcon_11hjw_226",ke="_timelineBody_11hjw_231",Ie="_timelineSummary_11hjw_236",Ee="_timelineTarget_11hjw_243",Oe="_timelineConfidence_11hjw_250",Le="_ownershipBadge_11hjw_259",Be="_confidenceExact_11hjw_267",$e="_confidencePartial_11hjw_272",Me="_confidenceAfterOnly_11hjw_277",Re="_confidenceIntentOnly_11hjw_282",Ae="_confidenceUnknown_11hjw_287",Ge="_timelineExpanded_11hjw_293",Ke="_empty_11hjw_365",Ve="_loading_11hjw_374",Fe="_error_11hjw_383",n={page:te,header:ne,backLink:ae,headerTitle:se,headerTime:ie,statusActive:ce,statusCompleted:re,section:oe,sectionTitle:le,summaryGrid:de,summaryCard:me,summaryCardActive:he,summaryIcon:ge,summaryCount:ue,summaryLabel:pe,contextGrid:ye,contextRow:xe,contextKey:fe,contextValue:_e,timelineFilter:je,filterLabel:we,filterSelect:ve,ownershipToggle:Se,timeline:Ce,timelineEntry:be,timelineTime:Ne,timelineIcon:Te,timelineBody:ke,timelineSummary:Ie,timelineTarget:Ee,timelineConfidence:Oe,ownershipBadge:Le,confidenceExact:Be,confidencePartial:$e,confidenceAfterOnly:Me,confidenceIntentOnly:Re,confidenceUnknown:Ae,timelineExpanded:Ge,empty:Ke,loading:Ve,error:Fe},D=[{key:"script",icon:"📝",labelKey:"changelog.category.script"},{key:"instance",icon:"🧱",labelKey:"changelog.category.instance"},{key:"property",icon:"🎨",labelKey:"changelog.category.property"},{key:"lighting",icon:"🌅",labelKey:"changelog.category.lighting"},{key:"terrain",icon:"⛰️",labelKey:"changelog.category.terrain"},{key:"asset",icon:"📦",labelKey:"changelog.category.asset"}];function F(t){if(!t)return"--:--";const s=new Date(t);return`${String(s.getHours()).padStart(2,"0")}:${String(s.getMinutes()).padStart(2,"0")}`}function De(t){if(!t)return"--:--:--";const s=new Date(t);return`${String(s.getHours()).padStart(2,"0")}:${String(s.getMinutes()).padStart(2,"0")}:${String(s.getSeconds()).padStart(2,"0")}`}function Pe(t,s){if(!t||!s)return"";const r=new Date(s).getTime()-new Date(t).getTime();return r<0?"":`${Math.round(r/6e4)}min`}function Ue(t){switch(t){case"exact":return n.confidenceExact;case"partial":return n.confidencePartial;case"after-only":return n.confidenceAfterOnly;case"intent-only":return n.confidenceIntentOnly;default:return n.confidenceUnknown}}function He(t,s){switch(s){case"exact":return t("changelog.detail.confidence.exact","Exact");case"partial":return t("changelog.detail.confidence.partial","Partial");case"after-only":return t("changelog.detail.confidence.afterOnly","After only");case"intent-only":return t("changelog.detail.confidence.intentOnly","Intent only");default:return t("changelog.detail.confidence.unknown","Unknown")}}function qe(t,s){switch(s){case"exact":return t("changelog.detail.confidence.exact.tooltip","Both the before and after state were confirmed for this change.");case"partial":return t("changelog.detail.confidence.partial.tooltip","Only part of the before and after state could be confirmed for this change.");case"after-only":return t("changelog.detail.confidence.afterOnly.tooltip","Only the resulting state after the change could be confirmed.");case"intent-only":return t("changelog.detail.confidence.intentOnly.tooltip","Only the requested action was recorded, not the resulting state.");default:return t("changelog.detail.confidence.unknown.tooltip","This change could not be confidently classified from the available data.")}}function We(t,s){switch(s){case"user_source":return t("changelog.ownership.userSource","User source");case"canonical_mirror":return t("changelog.ownership.canonicalMirror","Mirror metadata");case"generated":return t("changelog.ownership.generated","Generated");default:return null}}function Ye(t){const s=new URLSearchParams(t).get("placeId");if(!s)return null;const r=Number.parseInt(s,10);return Number.isInteger(r)&&r>=0?r:null}function et(){var S,C,b,N,T,k,I,x,E,f,g,m,d,_;const{t}=P(),{id:s}=U(),r=H(),p=q(),L=c.useMemo(()=>Ye(p.search),[p.search]),a=X(s,L),[h,w]=c.useState("all"),[y,B]=c.useState(!0),[$,M]=c.useState(null),v=c.useMemo(()=>{const i=y?a.changes:a.changes.filter(o=>o.artifactOwnership!=="generated");return[...h==="all"?i:i.filter(o=>o.category===h)].reverse()},[a.changes,h,y]),R=a.changes.some(i=>i.artifactOwnership==="generated");if(a.loading)return e.jsx("div",{className:n.loading,children:t("common.loading","Loading...")});if(a.error)return e.jsxs("div",{className:n.error,children:[a.error,e.jsx("br",{}),e.jsxs("span",{className:n.backLink,onClick:()=>r("/changelog"),children:["←"," ",t("changelog.detail.backToList","Back to list")]})]});const A=Pe(a.startTime,a.endTime),G=a.endTime?`${F(a.startTime)} → ${F(a.endTime)} (${A})`:`${F(a.startTime)} → ${t("changelog.card.inProgress","in progress")}`,K=!!((S=a.contextSummary)!=null&&S.intent||(C=a.contextSummary)!=null&&C.testScenario||(b=a.contextSummary)!=null&&b.expectedBehavior||(N=a.contextSummary)!=null&&N.observedBehavior),V=!!((T=a.verificationSummary)!=null&&T.label||(k=a.verificationSummary)!=null&&k.status||(I=a.verificationSummary)!=null&&I.testTimestamp);return e.jsxs("div",{className:n.page,children:[e.jsxs("div",{className:n.header,children:[e.jsxs("span",{className:n.backLink,onClick:()=>r("/changelog"),children:["←"," ",t("sidebar.changelog","Changelog")]}),e.jsx("span",{className:n.headerTitle,children:"|"}),e.jsx("span",{className:n.headerTime,children:G}),e.jsx(u,{text:a.status==="active"?t("changelog.card.active.tooltip","This session is still receiving new game changes."):t("changelog.card.completed.tooltip","This session has ended and no more changes are expected."),children:e.jsx("span",{className:a.status==="active"?n.statusActive:n.statusCompleted,children:a.status==="active"?t("changelog.card.active","Active"):t("changelog.card.completed","Completed")})})]}),e.jsxs("div",{className:n.section,children:[e.jsx("div",{className:n.sectionTitle,children:e.jsx(u,{text:t("changelog.detail.changeSummary.tooltip","Counts of extracted game changes grouped by category for this session."),children:e.jsx("span",{children:t("changelog.detail.changeSummary","Change Summary")})})}),e.jsx("div",{className:n.summaryGrid,children:D.map(i=>{const l=a.changeSummary;let o;switch(i.key){case"script":o=l.scriptsModified+l.scriptsCreated;break;case"instance":o=l.instancesCreated+l.instancesDeleted+l.instancesMoved;break;case"property":o=l.propertiesChanged;break;case"lighting":o=l.lightingChanged?1:0;break;case"terrain":o=l.terrainChanged?1:0;break;case"asset":o=l.assetsInserted;break;default:o=0}const j=h===i.key;return e.jsxs("div",{className:`${n.summaryCard} ${j?n.summaryCardActive:""}`,onClick:()=>w(j?"all":i.key),children:[e.jsx("span",{className:n.summaryIcon,children:i.icon}),e.jsx("div",{className:n.summaryCount,children:o}),e.jsx("div",{className:n.summaryLabel,children:t(i.labelKey,i.key)})]},i.key)})})]}),K&&e.jsxs("div",{className:n.section,children:[e.jsx("div",{className:n.sectionTitle,children:e.jsx(u,{text:t("changelog.detail.context.tooltip","Structured execution context captured for this changelog session."),children:e.jsx("span",{children:t("changelog.detail.context.title","Context Summary")})})}),e.jsxs("div",{className:n.contextGrid,children:[((x=a.contextSummary)==null?void 0:x.intent)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("changelog.card.sessionIntent","Session intent")}),e.jsx("span",{className:n.contextValue,children:a.contextSummary.intent})]}),((E=a.contextSummary)==null?void 0:E.testScenario)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("playtest.context.why","Why this test ran")}),e.jsx("span",{className:n.contextValue,children:a.contextSummary.testScenario})]}),((f=a.contextSummary)==null?void 0:f.expectedBehavior)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("playtest.context.expected","Expected")}),e.jsx("span",{className:n.contextValue,children:a.contextSummary.expectedBehavior})]}),((g=a.contextSummary)==null?void 0:g.observedBehavior)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("playtest.context.observed","Observed")}),e.jsx("span",{className:n.contextValue,children:a.contextSummary.observedBehavior})]})]})]}),V&&e.jsxs("div",{className:n.section,children:[e.jsx("div",{className:n.sectionTitle,children:e.jsx(u,{text:t("changelog.detail.verification.tooltip","Verification signals linked to this changelog session."),children:e.jsx("span",{children:t("changelog.detail.verification.title","Verification")})})}),e.jsxs("div",{className:n.contextGrid,children:[((m=a.verificationSummary)==null?void 0:m.label)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("changelog.detail.verification.label","Result")}),e.jsx("span",{className:n.contextValue,children:a.verificationSummary.label})]}),((d=a.verificationSummary)==null?void 0:d.status)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("changelog.detail.verification.status","Status")}),e.jsx("span",{className:n.contextValue,children:a.verificationSummary.status})]}),((_=a.verificationSummary)==null?void 0:_.testTimestamp)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("changelog.detail.verification.timestamp","Recorded at")}),e.jsx("span",{className:n.contextValue,children:a.verificationSummary.testTimestamp})]})]})]}),e.jsxs("div",{className:n.section,children:[e.jsx("div",{className:n.sectionTitle,children:e.jsx(u,{text:t("changelog.detail.changeTimeline.tooltip","Chronological list of extracted game changes for this session."),children:e.jsx("span",{children:t("changelog.detail.changeTimeline","Change Timeline")})})}),e.jsxs("div",{className:n.timelineFilter,children:[e.jsx("span",{className:n.filterLabel,children:e.jsx(W,{label:`${t("changelog.detail.filterCategory","Category")}:`,tooltip:t("changelog.detail.filterCategory.tooltip","Filter the timeline to a single change category.")})}),e.jsxs("select",{className:n.filterSelect,value:h,onChange:i=>w(i.target.value),children:[e.jsx("option",{value:"all",children:t("tools.filter.all","All")}),D.map(i=>e.jsxs("option",{value:i.key,children:[i.icon," ",t(i.labelKey,i.key)]},i.key))]}),R&&e.jsxs("label",{className:n.ownershipToggle,children:[e.jsx("input",{type:"checkbox",checked:y,onChange:i=>B(i.target.checked)}),t("changelog.ownership.showGenerated","Show generated metadata")]})]}),v.length===0?e.jsx("div",{className:n.empty,children:t("changelog.detail.noChanges","No changes in this category")}):e.jsx("div",{className:n.timeline,children:v.map((i,l)=>{const o=$===l,j=We(t,i.artifactOwnership);return e.jsxs("div",{children:[e.jsxs("div",{className:n.timelineEntry,onClick:()=>M(o?null:l),children:[e.jsx("span",{className:n.timelineTime,children:De(i.timestamp)}),e.jsx("span",{className:n.timelineIcon,children:ee(i.category)}),e.jsxs("div",{className:n.timelineBody,children:[e.jsxs("div",{className:n.timelineSummary,children:[i.summary,j&&e.jsx(z,{variant:i.artifactOwnership==="generated"?"neutral":"accent",className:n.ownershipBadge,children:j}),e.jsx(u,{text:qe(t,i.confidence),children:e.jsx("span",{className:`${n.timelineConfidence} ${Ue(i.confidence)}`,children:He(t,i.confidence)})})]}),e.jsx("div",{className:n.timelineTarget,children:i.target})]})]}),o&&e.jsx("div",{className:n.timelineExpanded,children:e.jsx(Y,{change:i})})]},l)})})]})]})}export{et as Component};
1
+ import{r as c,a as O,u as P,b as U,c as H,d as q,j as e}from"./index-C_exRd2o.js";import{I as W}from"./InfoLabel-HLPMIIL4.js";import{G as Y}from"./GameChangeDetail-Bd5Hg2ZD.js";import{T as u}from"./TooltipText-1fJvqtMt.js";import{B as z}from"./UiPrimitive-CsV5QE01.js";function J(t){const s={scriptsModified:0,scriptsCreated:0,instancesCreated:0,instancesDeleted:0,instancesMoved:0,propertiesChanged:0,lightingChanged:!1,terrainChanged:!1,assetsInserted:0};for(const r of t)switch(r.category){case"script":r.changeType==="create"?s.scriptsCreated++:s.scriptsModified++;break;case"instance":r.changeType==="create"?s.instancesCreated++:r.changeType==="delete"?s.instancesDeleted++:r.changeType==="move"&&s.instancesMoved++;break;case"property":s.propertiesChanged++;break;case"lighting":s.lightingChanged=!0;break;case"terrain":s.terrainChanged=!0;break;case"asset":s.assetsInserted++;break}return s}function Q(t){if(typeof t=="number")return{placeId:String(t)}}function X(t,s){const[r,p]=c.useState(""),[L,a]=c.useState(""),[h,w]=c.useState(),[y,B]=c.useState("completed"),[$,M]=c.useState([]),[v,R]=c.useState([]),[A,G]=c.useState([]),[K,V]=c.useState(),[S,C]=c.useState(),[b,N]=c.useState(),[T,k]=c.useState({scriptsModified:0,scriptsCreated:0,instancesCreated:0,instancesDeleted:0,instancesMoved:0,propertiesChanged:0,lightingChanged:!1,terrainChanged:!1,assetsInserted:0}),[I,x]=c.useState(!0),[E,f]=c.useState(null),g=c.useCallback(async()=>{if(t){x(!0),f(null);try{const m=Q(s),[d,_]=await Promise.all([m?O.get(`/api/dashboard/changelog/${t}`,m):O.get(`/api/dashboard/changelog/${t}`),m?O.get(`/api/dashboard/changelog/${t}/changes`,m):O.get(`/api/dashboard/changelog/${t}/changes`)]);p(d.entryId),a(d.startTime),w(d.endTime),B(d.status),M(d.entries),R(d.failures),V(d.contextSummary),C(d.replayMetadata),N(d.verificationSummary),G(_.changes),k(J(_.changes))}catch(m){f(m instanceof Error?m.message:"Failed to load changelog detail")}finally{x(!1)}}},[t,s]);return c.useEffect(()=>{g()},[g]),{entryId:r,startTime:L,endTime:h,status:y,entries:$,failures:v,changes:A,changeSummary:T,contextSummary:K,replayMetadata:S,verificationSummary:b,loading:I,error:E,refresh:g}}const Z={script:"📝",instance:"🧱",property:"🎨",lighting:"🌅",terrain:"⛰️",asset:"📦"};function ee(t){return Z[t]??"❓"}const te="_page_11hjw_2",ne="_header_11hjw_10",ae="_backLink_11hjw_16",se="_headerTitle_11hjw_29",ie="_headerTime_11hjw_37",ce="_statusActive_11hjw_44",re="_statusCompleted_11hjw_49",oe="_section_11hjw_54",le="_sectionTitle_11hjw_61",de="_summaryGrid_11hjw_74",me="_summaryCard_11hjw_80",he="_summaryCardActive_11hjw_94",ge="_summaryIcon_11hjw_99",ue="_summaryCount_11hjw_105",pe="_summaryLabel_11hjw_112",ye="_contextGrid_11hjw_121",xe="_contextRow_11hjw_127",fe="_contextKey_11hjw_133",_e="_contextValue_11hjw_141",je="_timelineFilter_11hjw_149",we="_filterLabel_11hjw_157",ve="_filterSelect_11hjw_163",Se="_ownershipToggle_11hjw_173",Ce="_timeline_11hjw_149",be="_timelineEntry_11hjw_201",Ne="_timelineTime_11hjw_218",Te="_timelineIcon_11hjw_226",ke="_timelineBody_11hjw_231",Ie="_timelineSummary_11hjw_236",Ee="_timelineTarget_11hjw_243",Oe="_timelineConfidence_11hjw_250",Le="_ownershipBadge_11hjw_259",Be="_confidenceExact_11hjw_267",$e="_confidencePartial_11hjw_272",Me="_confidenceAfterOnly_11hjw_277",Re="_confidenceIntentOnly_11hjw_282",Ae="_confidenceUnknown_11hjw_287",Ge="_timelineExpanded_11hjw_293",Ke="_empty_11hjw_365",Ve="_loading_11hjw_374",Fe="_error_11hjw_383",n={page:te,header:ne,backLink:ae,headerTitle:se,headerTime:ie,statusActive:ce,statusCompleted:re,section:oe,sectionTitle:le,summaryGrid:de,summaryCard:me,summaryCardActive:he,summaryIcon:ge,summaryCount:ue,summaryLabel:pe,contextGrid:ye,contextRow:xe,contextKey:fe,contextValue:_e,timelineFilter:je,filterLabel:we,filterSelect:ve,ownershipToggle:Se,timeline:Ce,timelineEntry:be,timelineTime:Ne,timelineIcon:Te,timelineBody:ke,timelineSummary:Ie,timelineTarget:Ee,timelineConfidence:Oe,ownershipBadge:Le,confidenceExact:Be,confidencePartial:$e,confidenceAfterOnly:Me,confidenceIntentOnly:Re,confidenceUnknown:Ae,timelineExpanded:Ge,empty:Ke,loading:Ve,error:Fe},D=[{key:"script",icon:"📝",labelKey:"changelog.category.script"},{key:"instance",icon:"🧱",labelKey:"changelog.category.instance"},{key:"property",icon:"🎨",labelKey:"changelog.category.property"},{key:"lighting",icon:"🌅",labelKey:"changelog.category.lighting"},{key:"terrain",icon:"⛰️",labelKey:"changelog.category.terrain"},{key:"asset",icon:"📦",labelKey:"changelog.category.asset"}];function F(t){if(!t)return"--:--";const s=new Date(t);return`${String(s.getHours()).padStart(2,"0")}:${String(s.getMinutes()).padStart(2,"0")}`}function De(t){if(!t)return"--:--:--";const s=new Date(t);return`${String(s.getHours()).padStart(2,"0")}:${String(s.getMinutes()).padStart(2,"0")}:${String(s.getSeconds()).padStart(2,"0")}`}function Pe(t,s){if(!t||!s)return"";const r=new Date(s).getTime()-new Date(t).getTime();return r<0?"":`${Math.round(r/6e4)}min`}function Ue(t){switch(t){case"exact":return n.confidenceExact;case"partial":return n.confidencePartial;case"after-only":return n.confidenceAfterOnly;case"intent-only":return n.confidenceIntentOnly;default:return n.confidenceUnknown}}function He(t,s){switch(s){case"exact":return t("changelog.detail.confidence.exact","Exact");case"partial":return t("changelog.detail.confidence.partial","Partial");case"after-only":return t("changelog.detail.confidence.afterOnly","After only");case"intent-only":return t("changelog.detail.confidence.intentOnly","Intent only");default:return t("changelog.detail.confidence.unknown","Unknown")}}function qe(t,s){switch(s){case"exact":return t("changelog.detail.confidence.exact.tooltip","Both the before and after state were confirmed for this change.");case"partial":return t("changelog.detail.confidence.partial.tooltip","Only part of the before and after state could be confirmed for this change.");case"after-only":return t("changelog.detail.confidence.afterOnly.tooltip","Only the resulting state after the change could be confirmed.");case"intent-only":return t("changelog.detail.confidence.intentOnly.tooltip","Only the requested action was recorded, not the resulting state.");default:return t("changelog.detail.confidence.unknown.tooltip","This change could not be confidently classified from the available data.")}}function We(t,s){switch(s){case"user_source":return t("changelog.ownership.userSource","User source");case"canonical_mirror":return t("changelog.ownership.canonicalMirror","Mirror metadata");case"generated":return t("changelog.ownership.generated","Generated");default:return null}}function Ye(t){const s=new URLSearchParams(t).get("placeId");if(!s)return null;const r=Number.parseInt(s,10);return Number.isInteger(r)&&r>=0?r:null}function et(){var S,C,b,N,T,k,I,x,E,f,g,m,d,_;const{t}=P(),{id:s}=U(),r=H(),p=q(),L=c.useMemo(()=>Ye(p.search),[p.search]),a=X(s,L),[h,w]=c.useState("all"),[y,B]=c.useState(!0),[$,M]=c.useState(null),v=c.useMemo(()=>{const i=y?a.changes:a.changes.filter(o=>o.artifactOwnership!=="generated");return[...h==="all"?i:i.filter(o=>o.category===h)].reverse()},[a.changes,h,y]),R=a.changes.some(i=>i.artifactOwnership==="generated");if(a.loading)return e.jsx("div",{className:n.loading,children:t("common.loading","Loading...")});if(a.error)return e.jsxs("div",{className:n.error,children:[a.error,e.jsx("br",{}),e.jsxs("span",{className:n.backLink,onClick:()=>r("/changelog"),children:["←"," ",t("changelog.detail.backToList","Back to list")]})]});const A=Pe(a.startTime,a.endTime),G=a.endTime?`${F(a.startTime)} → ${F(a.endTime)} (${A})`:`${F(a.startTime)} → ${t("changelog.card.inProgress","in progress")}`,K=!!((S=a.contextSummary)!=null&&S.intent||(C=a.contextSummary)!=null&&C.testScenario||(b=a.contextSummary)!=null&&b.expectedBehavior||(N=a.contextSummary)!=null&&N.observedBehavior),V=!!((T=a.verificationSummary)!=null&&T.label||(k=a.verificationSummary)!=null&&k.status||(I=a.verificationSummary)!=null&&I.testTimestamp);return e.jsxs("div",{className:n.page,children:[e.jsxs("div",{className:n.header,children:[e.jsxs("span",{className:n.backLink,onClick:()=>r("/changelog"),children:["←"," ",t("sidebar.changelog","Changelog")]}),e.jsx("span",{className:n.headerTitle,children:"|"}),e.jsx("span",{className:n.headerTime,children:G}),e.jsx(u,{text:a.status==="active"?t("changelog.card.active.tooltip","This session is still receiving new game changes."):t("changelog.card.completed.tooltip","This session has ended and no more changes are expected."),children:e.jsx("span",{className:a.status==="active"?n.statusActive:n.statusCompleted,children:a.status==="active"?t("changelog.card.active","Active"):t("changelog.card.completed","Completed")})})]}),e.jsxs("div",{className:n.section,children:[e.jsx("div",{className:n.sectionTitle,children:e.jsx(u,{text:t("changelog.detail.changeSummary.tooltip","Counts of extracted game changes grouped by category for this session."),children:e.jsx("span",{children:t("changelog.detail.changeSummary","Change Summary")})})}),e.jsx("div",{className:n.summaryGrid,children:D.map(i=>{const l=a.changeSummary;let o;switch(i.key){case"script":o=l.scriptsModified+l.scriptsCreated;break;case"instance":o=l.instancesCreated+l.instancesDeleted+l.instancesMoved;break;case"property":o=l.propertiesChanged;break;case"lighting":o=l.lightingChanged?1:0;break;case"terrain":o=l.terrainChanged?1:0;break;case"asset":o=l.assetsInserted;break;default:o=0}const j=h===i.key;return e.jsxs("div",{className:`${n.summaryCard} ${j?n.summaryCardActive:""}`,onClick:()=>w(j?"all":i.key),children:[e.jsx("span",{className:n.summaryIcon,children:i.icon}),e.jsx("div",{className:n.summaryCount,children:o}),e.jsx("div",{className:n.summaryLabel,children:t(i.labelKey,i.key)})]},i.key)})})]}),K&&e.jsxs("div",{className:n.section,children:[e.jsx("div",{className:n.sectionTitle,children:e.jsx(u,{text:t("changelog.detail.context.tooltip","Structured execution context captured for this changelog session."),children:e.jsx("span",{children:t("changelog.detail.context.title","Context Summary")})})}),e.jsxs("div",{className:n.contextGrid,children:[((x=a.contextSummary)==null?void 0:x.intent)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("changelog.card.sessionIntent","Session intent")}),e.jsx("span",{className:n.contextValue,children:a.contextSummary.intent})]}),((E=a.contextSummary)==null?void 0:E.testScenario)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("playtest.context.why","Why this test ran")}),e.jsx("span",{className:n.contextValue,children:a.contextSummary.testScenario})]}),((f=a.contextSummary)==null?void 0:f.expectedBehavior)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("playtest.context.expected","Expected")}),e.jsx("span",{className:n.contextValue,children:a.contextSummary.expectedBehavior})]}),((g=a.contextSummary)==null?void 0:g.observedBehavior)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("playtest.context.observed","Observed")}),e.jsx("span",{className:n.contextValue,children:a.contextSummary.observedBehavior})]})]})]}),V&&e.jsxs("div",{className:n.section,children:[e.jsx("div",{className:n.sectionTitle,children:e.jsx(u,{text:t("changelog.detail.verification.tooltip","Verification signals linked to this changelog session."),children:e.jsx("span",{children:t("changelog.detail.verification.title","Verification")})})}),e.jsxs("div",{className:n.contextGrid,children:[((m=a.verificationSummary)==null?void 0:m.label)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("changelog.detail.verification.label","Result")}),e.jsx("span",{className:n.contextValue,children:a.verificationSummary.label})]}),((d=a.verificationSummary)==null?void 0:d.status)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("changelog.detail.verification.status","Status")}),e.jsx("span",{className:n.contextValue,children:a.verificationSummary.status})]}),((_=a.verificationSummary)==null?void 0:_.testTimestamp)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("changelog.detail.verification.timestamp","Recorded at")}),e.jsx("span",{className:n.contextValue,children:a.verificationSummary.testTimestamp})]})]})]}),e.jsxs("div",{className:n.section,children:[e.jsx("div",{className:n.sectionTitle,children:e.jsx(u,{text:t("changelog.detail.changeTimeline.tooltip","Chronological list of extracted game changes for this session."),children:e.jsx("span",{children:t("changelog.detail.changeTimeline","Change Timeline")})})}),e.jsxs("div",{className:n.timelineFilter,children:[e.jsx("span",{className:n.filterLabel,children:e.jsx(W,{label:`${t("changelog.detail.filterCategory","Category")}:`,tooltip:t("changelog.detail.filterCategory.tooltip","Filter the timeline to a single change category.")})}),e.jsxs("select",{className:n.filterSelect,value:h,onChange:i=>w(i.target.value),children:[e.jsx("option",{value:"all",children:t("tools.filter.all","All")}),D.map(i=>e.jsxs("option",{value:i.key,children:[i.icon," ",t(i.labelKey,i.key)]},i.key))]}),R&&e.jsxs("label",{className:n.ownershipToggle,children:[e.jsx("input",{type:"checkbox",checked:y,onChange:i=>B(i.target.checked)}),t("changelog.ownership.showGenerated","Show generated metadata")]})]}),v.length===0?e.jsx("div",{className:n.empty,children:t("changelog.detail.noChanges","No changes in this category")}):e.jsx("div",{className:n.timeline,children:v.map((i,l)=>{const o=$===l,j=We(t,i.artifactOwnership);return e.jsxs("div",{children:[e.jsxs("div",{className:n.timelineEntry,onClick:()=>M(o?null:l),children:[e.jsx("span",{className:n.timelineTime,children:De(i.timestamp)}),e.jsx("span",{className:n.timelineIcon,children:ee(i.category)}),e.jsxs("div",{className:n.timelineBody,children:[e.jsxs("div",{className:n.timelineSummary,children:[i.summary,j&&e.jsx(z,{variant:i.artifactOwnership==="generated"?"neutral":"accent",className:n.ownershipBadge,children:j}),e.jsx(u,{text:qe(t,i.confidence),children:e.jsx("span",{className:`${n.timelineConfidence} ${Ue(i.confidence)}`,children:He(t,i.confidence)})})]}),e.jsx("div",{className:n.timelineTarget,children:i.target})]})]}),o&&e.jsx("div",{className:n.timelineExpanded,children:e.jsx(Y,{change:i})})]},l)})})]})]})}export{et as Component};
@@ -1 +1 @@
1
- import{r as l,a as F,D,u as M,j as e,e as O,c as V,h as U,l as K,T as G}from"./index-B1MZBjK4.js";import{P as H}from"./PageHeader-DezmLDg1.js";import{C as Z}from"./ConfirmModal-BXbkJq3w.js";import{C as Q}from"./CurrentPlaceScope-DJheb09C.js";import{T as k}from"./TooltipText-CMx5IM6p.js";import{T as q}from"./Tabs-iku37C2G.js";import"./UiPrimitive-ojecpNs1.js";import"./ConfirmModal.module-DJksQHBd.js";const z=10;function J(t,o){return typeof o!="number"?t:`${t}?placeId=${encodeURIComponent(String(o))}`}function W(t){const o=(t==null?void 0:t.placeId)??null,[s,n]=l.useState([]),[u,_]=l.useState(0),[a,f]=l.useState(!1),[x,v]=l.useState(!0),[g,C]=l.useState(0),[d,y]=l.useState("all"),N=l.useRef(null),m=l.useCallback(async(h,b)=>{v(!0);try{const j={limit:String(z),offset:String(h)};b!=="all"&&(j.status=b),typeof o=="number"&&(j.placeId=String(o));const I=await F.get("/api/dashboard/changelog",j);n(I.entries),_(I.total),f(I.hasMore)}catch{n([]),_(0),f(!1)}finally{v(!1)}},[o]),S=l.useCallback(()=>{m(g,d)},[m,g,d]),i=l.useCallback(async()=>{await F.post(J("/api/dashboard/changelog/clear",o)),n([]),_(0),f(!1)},[o]);return l.useEffect(()=>{m(g,d)},[m,g,d]),l.useEffect(()=>{const h=new D;N.current=h,h.connect();const b=h.on("command",()=>{m(g,d)});return()=>{b(),h.disconnect(),N.current=null}},[m,g,d]),{entries:s,total:u,hasMore:a,loading:x,offset:g,statusFilter:d,setOffset:C,setStatusFilter:y,refresh:S,clear:i}}const X="_card_1n89u_2",Y="_header_1n89u_17",ee="_statusBadge_1n89u_24",te="_statusDot_1n89u_35",se="_active_1n89u_41",ae="_completed_1n89u_50",ne="_timeRange_1n89u_58",ce="_summaryList_1n89u_65",oe="_summaryItem_1n89u_71",ie="_summaryIcon_1n89u_80",le="_summaryText_1n89u_86",re="_progressBar_1n89u_91",ge="_progressFill_1n89u_99",de="_emptySummary_1n89u_112",me="_contextBlock_1n89u_120",he="_contextLabel_1n89u_129",pe="_contextValue_1n89u_137",c={card:X,header:Y,statusBadge:ee,statusDot:te,active:se,completed:ae,timeRange:ne,summaryList:ce,summaryItem:oe,summaryIcon:ie,summaryText:le,progressBar:re,progressFill:ge,emptySummary:de,contextBlock:me,contextLabel:he,contextValue:pe};function R(t){if(!t)return"--:--";const o=new Date(t);return`${String(o.getHours()).padStart(2,"0")}:${String(o.getMinutes()).padStart(2,"0")}`}function ue({entry:t,onClick:o}){var h,b,j,I,B,L,A,P,w,E;const{t:s}=M(),n=t.changeSummary,u=t.status==="active",_=t.isBootstrapOnly===!0,a=[],f=n.scriptsModified+n.scriptsCreated;if(f>0){const p=[];n.scriptsModified>0&&p.push(`${n.scriptsModified} ${s("changelog.card.modified","modified")}`),n.scriptsCreated>0&&p.push(`${n.scriptsCreated} ${s("changelog.card.created","created")}`);const T=`${f} ${s("changelog.card.scripts","scripts")} ${p.join(", ")}`;a.push({icon:"📝",text:T,tooltip:s("changelog.card.scripts.tooltip","Script changes made in this session.")})}const x=n.instancesCreated+n.instancesDeleted+n.instancesMoved;if(x>0){const p=[];n.instancesCreated>0&&p.push(`${n.instancesCreated} ${s("changelog.card.created","created")}`),n.instancesDeleted>0&&p.push(`${n.instancesDeleted} ${s("changelog.card.deleted","deleted")}`),n.instancesMoved>0&&p.push(`${n.instancesMoved} ${s("changelog.card.moved","moved")}`);const T=`${x} ${s("changelog.card.instances","instances")} ${p.join(", ")}`;a.push({icon:"🧱",text:T,tooltip:s("changelog.card.instances.tooltip","Instance create, delete, move, or clone changes in this session.")})}n.propertiesChanged>0&&a.push({icon:"🎨",text:`${n.propertiesChanged} ${s("changelog.card.propertiesChanged","properties changed")}`,tooltip:s("changelog.card.propertiesChanged.tooltip","Property value changes recorded for this session.")}),n.lightingChanged&&a.push({icon:"🌅",text:s("changelog.card.lightingConfigured","Lighting configured"),tooltip:s("changelog.card.lightingConfigured.tooltip","Lighting or atmosphere settings changed in this session.")}),n.terrainChanged&&a.push({icon:"⛰️",text:s("changelog.card.terrainConfigured","Terrain configured"),tooltip:s("changelog.card.terrainConfigured.tooltip","Terrain data or terrain settings changed in this session.")}),n.assetsInserted>0&&a.push({icon:"📦",text:`${n.assetsInserted} ${s("changelog.card.assetsInserted","assets inserted")}`,tooltip:s("changelog.card.assetsInserted.tooltip","Assets inserted into the place during this session.")});const v=R(t.startTime),g=u?s("changelog.card.inProgress","in progress"):t.endTime?R(t.endTime):"--:--",C=_?s("changelog.card.bootstrapStatus","Bootstrap"):u?s("changelog.card.active","Active"):s("changelog.card.completed","Completed"),d=_?s("changelog.card.bootstrapStatus.tooltip","This session only contains the initial sync bootstrap snapshot."):u?s("changelog.card.active.tooltip","This session is still receiving new game changes."):s("changelog.card.completed.tooltip","This session has ended and no more changes are expected."),y=_?s("changelog.card.bootstrapSummary","Initial sync snapshot"):s("changelog.card.noChanges","No changes yet"),N=_?s("changelog.card.bootstrapSummary.tooltip","Initial file sync writes are collapsed into a single bootstrap snapshot row."):s("changelog.card.noChanges.tooltip","No game changes have been extracted for this session yet."),m=(b=(h=t.contextSummary)==null?void 0:h.intent)==null?void 0:b.trim(),S=((L=(B=(I=(j=t.contextSummary)==null?void 0:j.affectedAreas)==null?void 0:I[0])==null?void 0:B.label)==null?void 0:L.trim())||((P=(A=t.contextSummary)==null?void 0:A.testScenario)==null?void 0:P.trim()),i=(E=(w=t.verificationSummary)==null?void 0:w.label)==null?void 0:E.trim();return e.jsxs("div",{className:c.card,onClick:o,children:[e.jsxs("div",{className:c.header,children:[e.jsx(k,{text:d,children:e.jsxs("span",{className:`${c.statusBadge} ${u?c.active:c.completed}`,children:[e.jsx("span",{className:c.statusDot}),C]})}),e.jsxs("span",{className:c.timeRange,children:[v,"~",g]})]}),e.jsx("div",{className:c.summaryList,children:a.length>0?a.map((p,T)=>e.jsxs("div",{className:c.summaryItem,children:[e.jsx("span",{className:c.summaryIcon,children:p.icon}),e.jsx(k,{text:p.tooltip,children:e.jsx("span",{className:c.summaryText,children:p.text})})]},T)):e.jsx(k,{text:N,children:e.jsx("span",{className:c.emptySummary,style:{display:"block"},children:y})})}),m&&e.jsxs("div",{className:c.contextBlock,children:[e.jsx("span",{className:c.contextLabel,children:s("changelog.card.sessionIntent","Session intent")}),e.jsx("span",{className:c.contextValue,children:m})]}),!m&&S&&e.jsxs("div",{className:c.contextBlock,children:[e.jsx("span",{className:c.contextLabel,children:s("changelog.card.representativeArea","Representative area")}),e.jsx("span",{className:c.contextValue,children:S})]}),i&&e.jsxs("div",{className:c.contextBlock,children:[e.jsx("span",{className:c.contextLabel,children:s("changelog.card.verification","Verification")}),e.jsx("span",{className:c.contextValue,children:i})]}),u&&e.jsx("div",{className:c.progressBar,children:e.jsx("div",{className:c.progressFill})})]})}const _e="_page_1tggr_2",fe="_limitNotice_1tggr_9",xe="_limitNoticeContent_1tggr_23",ye="_limitNoticeTitle_1tggr_28",be="_limitNoticeText_1tggr_35",ve="_primaryAction_1tggr_41",Ce="_clearButton_1tggr_67",Ne="_list_1tggr_88",Se="_empty_1tggr_95",je="_loading_1tggr_104",Ie="_pagination_1tggr_113",Te="_pageInfo_1tggr_121",$e="_btn_1tggr_127",r={page:_e,limitNotice:fe,limitNoticeContent:xe,limitNoticeTitle:ye,limitNoticeText:be,primaryAction:ve,clearButton:Ce,list:Ne,empty:Se,loading:je,pagination:Ie,pageInfo:Te,btn:$e},$=10;function ke(t,o){return typeof o!="number"?`/changelog/${t}`:`/changelog/${t}?placeId=${encodeURIComponent(String(o))}`}const Be=[{key:"all",labelKey:"changelog.filter.all"},{key:"active",labelKey:"changelog.filter.active"},{key:"completed",labelKey:"changelog.filter.completed"}];function De(){const{t}=M(),{trackEvent:o,trackPageView:s}=O(),n=V(),[u,_]=l.useState(null),a=W({placeId:u}),f=U(),{show:x}=K(),[v,g]=l.useState(!1),[C,d]=l.useState(!1),y=!f.loading&&f.tier==="basic",N=y?a.entries.slice(0,3):a.entries,m=!y&&a.total>$,S=async()=>{d(!0);try{await a.clear(),x(t("toast.clearSuccess","Cleared successfully"),"success"),g(!1)}catch{x(t("toast.clearFailed","Failed to clear data"),"error")}finally{d(!1)}};return e.jsxs("div",{className:r.page,children:[e.jsx(H,{title:t("page.changelog.title","Changelog"),description:t("page.changelog.description","Review game-change sessions captured from AI actions and sync events."),helpTopicId:"changelog",helpState:{tier:f.tier}}),e.jsx(Q,{surface:"changelog",selectable:!0,selectedPlaceId:u,onSelectedPlaceIdChange:i=>{_(i),a.setOffset(0)}}),e.jsx(q,{items:Be.map(i=>({key:i.key,label:t(i.labelKey,i.key.charAt(0).toUpperCase()+i.key.slice(1))})),value:a.statusFilter,onChange:i=>{const h=`changelog_${i}`;o("dashboard_click_event",{click_target:`changelog_tab_${i}`,page:"changelog",tab:h}),s({page:"changelog",tab:h}),a.setStatusFilter(i),a.setOffset(0)},rightActions:e.jsx("button",{className:r.clearButton,onClick:()=>{o("dashboard_click_event",{click_target:"changelog_clear",page:"changelog",tab:`changelog_${a.statusFilter}`}),g(!0)},children:t("common.clear","Clear")})}),a.loading&&a.entries.length===0&&e.jsx("div",{className:r.loading,children:t("common.loading","Loading...")}),!a.loading&&a.entries.length===0?e.jsx("div",{className:r.empty,children:t("changelog.empty","No changelog entries for the current place yet")}):e.jsx("div",{className:r.list,children:N.map(i=>e.jsx(ue,{entry:i,onClick:()=>n(ke(i.entryId,u))},i.entryId))}),m&&e.jsxs("div",{className:r.pagination,children:[e.jsx("button",{className:r.btn,disabled:a.offset===0,onClick:()=>a.setOffset(Math.max(0,a.offset-$)),children:t("tools.page.prev","Prev")}),e.jsxs("span",{className:r.pageInfo,children:[a.offset+1,"–",Math.min(a.offset+$,a.total)," / ",a.total]}),e.jsx("button",{className:r.btn,disabled:!a.hasMore,onClick:()=>a.setOffset(a.offset+$),children:t("tools.page.next","Next")})]}),y&&e.jsx(e.Fragment,{children:e.jsxs("div",{className:r.limitNotice,children:[e.jsxs("div",{className:r.limitNoticeContent,children:[e.jsx("div",{className:r.limitNoticeTitle,children:t("changelog.basic.limit.title","Basic preview shows the latest 3 sessions")}),e.jsx("div",{className:r.limitNoticeText,children:t("changelog.basic.limit.body","Full changelog timeline browsing is available with Pro.")})]}),e.jsx("a",{className:r.primaryAction,href:G.changelog,target:"_blank",rel:"noreferrer",onClick:()=>o("dashboard_click_event",{click_target:"upgrade_cta",placement:"changelog_limit_notice",page:"changelog",tab:`changelog_${a.statusFilter}`}),children:t("tier.upgrade","View Pro")})]})}),e.jsx(Z,{open:v,title:t("changelog.clear.title","Clear changelog?"),message:t("changelog.clear.message","This permanently removes the stored changelog for the current place."),cancelLabel:t("common.cancel","Cancel"),confirmLabel:t("common.clear","Clear"),loading:C,onCancel:()=>!C&&g(!1),onConfirm:S})]})}export{De as Component};
1
+ import{r as l,a as F,D,u as M,j as e,e as O,c as V,h as U,l as K,T as G}from"./index-C_exRd2o.js";import{P as H}from"./PageHeader-Cvi0LO4r.js";import{C as Z}from"./ConfirmModal-DJp4ax33.js";import{C as Q}from"./CurrentPlaceScope-DrtUw6py.js";import{T as k}from"./TooltipText-1fJvqtMt.js";import{T as q}from"./Tabs-2QEkInbt.js";import"./UiPrimitive-CsV5QE01.js";import"./ConfirmModal.module-DJksQHBd.js";const z=10;function J(t,o){return typeof o!="number"?t:`${t}?placeId=${encodeURIComponent(String(o))}`}function W(t){const o=(t==null?void 0:t.placeId)??null,[s,n]=l.useState([]),[u,_]=l.useState(0),[a,f]=l.useState(!1),[x,v]=l.useState(!0),[g,C]=l.useState(0),[d,y]=l.useState("all"),N=l.useRef(null),m=l.useCallback(async(h,b)=>{v(!0);try{const j={limit:String(z),offset:String(h)};b!=="all"&&(j.status=b),typeof o=="number"&&(j.placeId=String(o));const I=await F.get("/api/dashboard/changelog",j);n(I.entries),_(I.total),f(I.hasMore)}catch{n([]),_(0),f(!1)}finally{v(!1)}},[o]),S=l.useCallback(()=>{m(g,d)},[m,g,d]),i=l.useCallback(async()=>{await F.post(J("/api/dashboard/changelog/clear",o)),n([]),_(0),f(!1)},[o]);return l.useEffect(()=>{m(g,d)},[m,g,d]),l.useEffect(()=>{const h=new D;N.current=h,h.connect();const b=h.on("command",()=>{m(g,d)});return()=>{b(),h.disconnect(),N.current=null}},[m,g,d]),{entries:s,total:u,hasMore:a,loading:x,offset:g,statusFilter:d,setOffset:C,setStatusFilter:y,refresh:S,clear:i}}const X="_card_1n89u_2",Y="_header_1n89u_17",ee="_statusBadge_1n89u_24",te="_statusDot_1n89u_35",se="_active_1n89u_41",ae="_completed_1n89u_50",ne="_timeRange_1n89u_58",ce="_summaryList_1n89u_65",oe="_summaryItem_1n89u_71",ie="_summaryIcon_1n89u_80",le="_summaryText_1n89u_86",re="_progressBar_1n89u_91",ge="_progressFill_1n89u_99",de="_emptySummary_1n89u_112",me="_contextBlock_1n89u_120",he="_contextLabel_1n89u_129",pe="_contextValue_1n89u_137",c={card:X,header:Y,statusBadge:ee,statusDot:te,active:se,completed:ae,timeRange:ne,summaryList:ce,summaryItem:oe,summaryIcon:ie,summaryText:le,progressBar:re,progressFill:ge,emptySummary:de,contextBlock:me,contextLabel:he,contextValue:pe};function R(t){if(!t)return"--:--";const o=new Date(t);return`${String(o.getHours()).padStart(2,"0")}:${String(o.getMinutes()).padStart(2,"0")}`}function ue({entry:t,onClick:o}){var h,b,j,I,B,L,A,P,w,E;const{t:s}=M(),n=t.changeSummary,u=t.status==="active",_=t.isBootstrapOnly===!0,a=[],f=n.scriptsModified+n.scriptsCreated;if(f>0){const p=[];n.scriptsModified>0&&p.push(`${n.scriptsModified} ${s("changelog.card.modified","modified")}`),n.scriptsCreated>0&&p.push(`${n.scriptsCreated} ${s("changelog.card.created","created")}`);const T=`${f} ${s("changelog.card.scripts","scripts")} ${p.join(", ")}`;a.push({icon:"📝",text:T,tooltip:s("changelog.card.scripts.tooltip","Script changes made in this session.")})}const x=n.instancesCreated+n.instancesDeleted+n.instancesMoved;if(x>0){const p=[];n.instancesCreated>0&&p.push(`${n.instancesCreated} ${s("changelog.card.created","created")}`),n.instancesDeleted>0&&p.push(`${n.instancesDeleted} ${s("changelog.card.deleted","deleted")}`),n.instancesMoved>0&&p.push(`${n.instancesMoved} ${s("changelog.card.moved","moved")}`);const T=`${x} ${s("changelog.card.instances","instances")} ${p.join(", ")}`;a.push({icon:"🧱",text:T,tooltip:s("changelog.card.instances.tooltip","Instance create, delete, move, or clone changes in this session.")})}n.propertiesChanged>0&&a.push({icon:"🎨",text:`${n.propertiesChanged} ${s("changelog.card.propertiesChanged","properties changed")}`,tooltip:s("changelog.card.propertiesChanged.tooltip","Property value changes recorded for this session.")}),n.lightingChanged&&a.push({icon:"🌅",text:s("changelog.card.lightingConfigured","Lighting configured"),tooltip:s("changelog.card.lightingConfigured.tooltip","Lighting or atmosphere settings changed in this session.")}),n.terrainChanged&&a.push({icon:"⛰️",text:s("changelog.card.terrainConfigured","Terrain configured"),tooltip:s("changelog.card.terrainConfigured.tooltip","Terrain data or terrain settings changed in this session.")}),n.assetsInserted>0&&a.push({icon:"📦",text:`${n.assetsInserted} ${s("changelog.card.assetsInserted","assets inserted")}`,tooltip:s("changelog.card.assetsInserted.tooltip","Assets inserted into the place during this session.")});const v=R(t.startTime),g=u?s("changelog.card.inProgress","in progress"):t.endTime?R(t.endTime):"--:--",C=_?s("changelog.card.bootstrapStatus","Bootstrap"):u?s("changelog.card.active","Active"):s("changelog.card.completed","Completed"),d=_?s("changelog.card.bootstrapStatus.tooltip","This session only contains the initial sync bootstrap snapshot."):u?s("changelog.card.active.tooltip","This session is still receiving new game changes."):s("changelog.card.completed.tooltip","This session has ended and no more changes are expected."),y=_?s("changelog.card.bootstrapSummary","Initial sync snapshot"):s("changelog.card.noChanges","No changes yet"),N=_?s("changelog.card.bootstrapSummary.tooltip","Initial file sync writes are collapsed into a single bootstrap snapshot row."):s("changelog.card.noChanges.tooltip","No game changes have been extracted for this session yet."),m=(b=(h=t.contextSummary)==null?void 0:h.intent)==null?void 0:b.trim(),S=((L=(B=(I=(j=t.contextSummary)==null?void 0:j.affectedAreas)==null?void 0:I[0])==null?void 0:B.label)==null?void 0:L.trim())||((P=(A=t.contextSummary)==null?void 0:A.testScenario)==null?void 0:P.trim()),i=(E=(w=t.verificationSummary)==null?void 0:w.label)==null?void 0:E.trim();return e.jsxs("div",{className:c.card,onClick:o,children:[e.jsxs("div",{className:c.header,children:[e.jsx(k,{text:d,children:e.jsxs("span",{className:`${c.statusBadge} ${u?c.active:c.completed}`,children:[e.jsx("span",{className:c.statusDot}),C]})}),e.jsxs("span",{className:c.timeRange,children:[v,"~",g]})]}),e.jsx("div",{className:c.summaryList,children:a.length>0?a.map((p,T)=>e.jsxs("div",{className:c.summaryItem,children:[e.jsx("span",{className:c.summaryIcon,children:p.icon}),e.jsx(k,{text:p.tooltip,children:e.jsx("span",{className:c.summaryText,children:p.text})})]},T)):e.jsx(k,{text:N,children:e.jsx("span",{className:c.emptySummary,style:{display:"block"},children:y})})}),m&&e.jsxs("div",{className:c.contextBlock,children:[e.jsx("span",{className:c.contextLabel,children:s("changelog.card.sessionIntent","Session intent")}),e.jsx("span",{className:c.contextValue,children:m})]}),!m&&S&&e.jsxs("div",{className:c.contextBlock,children:[e.jsx("span",{className:c.contextLabel,children:s("changelog.card.representativeArea","Representative area")}),e.jsx("span",{className:c.contextValue,children:S})]}),i&&e.jsxs("div",{className:c.contextBlock,children:[e.jsx("span",{className:c.contextLabel,children:s("changelog.card.verification","Verification")}),e.jsx("span",{className:c.contextValue,children:i})]}),u&&e.jsx("div",{className:c.progressBar,children:e.jsx("div",{className:c.progressFill})})]})}const _e="_page_1tggr_2",fe="_limitNotice_1tggr_9",xe="_limitNoticeContent_1tggr_23",ye="_limitNoticeTitle_1tggr_28",be="_limitNoticeText_1tggr_35",ve="_primaryAction_1tggr_41",Ce="_clearButton_1tggr_67",Ne="_list_1tggr_88",Se="_empty_1tggr_95",je="_loading_1tggr_104",Ie="_pagination_1tggr_113",Te="_pageInfo_1tggr_121",$e="_btn_1tggr_127",r={page:_e,limitNotice:fe,limitNoticeContent:xe,limitNoticeTitle:ye,limitNoticeText:be,primaryAction:ve,clearButton:Ce,list:Ne,empty:Se,loading:je,pagination:Ie,pageInfo:Te,btn:$e},$=10;function ke(t,o){return typeof o!="number"?`/changelog/${t}`:`/changelog/${t}?placeId=${encodeURIComponent(String(o))}`}const Be=[{key:"all",labelKey:"changelog.filter.all"},{key:"active",labelKey:"changelog.filter.active"},{key:"completed",labelKey:"changelog.filter.completed"}];function De(){const{t}=M(),{trackEvent:o,trackPageView:s}=O(),n=V(),[u,_]=l.useState(null),a=W({placeId:u}),f=U(),{show:x}=K(),[v,g]=l.useState(!1),[C,d]=l.useState(!1),y=!f.loading&&f.tier==="basic",N=y?a.entries.slice(0,3):a.entries,m=!y&&a.total>$,S=async()=>{d(!0);try{await a.clear(),x(t("toast.clearSuccess","Cleared successfully"),"success"),g(!1)}catch{x(t("toast.clearFailed","Failed to clear data"),"error")}finally{d(!1)}};return e.jsxs("div",{className:r.page,children:[e.jsx(H,{title:t("page.changelog.title","Changelog"),description:t("page.changelog.description","Review game-change sessions captured from AI actions and sync events."),helpTopicId:"changelog",helpState:{tier:f.tier}}),e.jsx(Q,{surface:"changelog",selectable:!0,selectedPlaceId:u,onSelectedPlaceIdChange:i=>{_(i),a.setOffset(0)}}),e.jsx(q,{items:Be.map(i=>({key:i.key,label:t(i.labelKey,i.key.charAt(0).toUpperCase()+i.key.slice(1))})),value:a.statusFilter,onChange:i=>{const h=`changelog_${i}`;o("dashboard_click_event",{click_target:`changelog_tab_${i}`,page:"changelog",tab:h}),s({page:"changelog",tab:h}),a.setStatusFilter(i),a.setOffset(0)},rightActions:e.jsx("button",{className:r.clearButton,onClick:()=>{o("dashboard_click_event",{click_target:"changelog_clear",page:"changelog",tab:`changelog_${a.statusFilter}`}),g(!0)},children:t("common.clear","Clear")})}),a.loading&&a.entries.length===0&&e.jsx("div",{className:r.loading,children:t("common.loading","Loading...")}),!a.loading&&a.entries.length===0?e.jsx("div",{className:r.empty,children:t("changelog.empty","No changelog entries for the current place yet")}):e.jsx("div",{className:r.list,children:N.map(i=>e.jsx(ue,{entry:i,onClick:()=>n(ke(i.entryId,u))},i.entryId))}),m&&e.jsxs("div",{className:r.pagination,children:[e.jsx("button",{className:r.btn,disabled:a.offset===0,onClick:()=>a.setOffset(Math.max(0,a.offset-$)),children:t("tools.page.prev","Prev")}),e.jsxs("span",{className:r.pageInfo,children:[a.offset+1,"–",Math.min(a.offset+$,a.total)," / ",a.total]}),e.jsx("button",{className:r.btn,disabled:!a.hasMore,onClick:()=>a.setOffset(a.offset+$),children:t("tools.page.next","Next")})]}),y&&e.jsx(e.Fragment,{children:e.jsxs("div",{className:r.limitNotice,children:[e.jsxs("div",{className:r.limitNoticeContent,children:[e.jsx("div",{className:r.limitNoticeTitle,children:t("changelog.basic.limit.title","Basic preview shows the latest 3 sessions")}),e.jsx("div",{className:r.limitNoticeText,children:t("changelog.basic.limit.body","Full changelog timeline browsing is available with Pro.")})]}),e.jsx("a",{className:r.primaryAction,href:G.changelog,target:"_blank",rel:"noreferrer",onClick:()=>o("dashboard_click_event",{click_target:"upgrade_cta",placement:"changelog_limit_notice",page:"changelog",tab:`changelog_${a.statusFilter}`}),children:t("tier.upgrade","View Pro")})]})}),e.jsx(Z,{open:v,title:t("changelog.clear.title","Clear changelog?"),message:t("changelog.clear.message","This permanently removes the stored changelog for the current place."),cancelLabel:t("common.cancel","Cancel"),confirmLabel:t("common.clear","Clear"),loading:C,onCancel:()=>!C&&g(!1),onConfirm:S})]})}export{De as Component};
@@ -1 +1 @@
1
- import{r as u,j as s}from"./index-B1MZBjK4.js";import{s as a}from"./ConfirmModal.module-DJksQHBd.js";function p({open:r,title:t,message:o,cancelLabel:c,confirmLabel:n,loading:e=!1,onCancel:l,onConfirm:d}){const i=u.useId();return r?s.jsx("div",{className:a.backdrop,onClick:e?void 0:l,children:s.jsxs("div",{className:a.modal,role:"dialog","aria-modal":"true","aria-labelledby":i,onClick:m=>m.stopPropagation(),children:[s.jsx("h2",{id:i,className:a.title,children:t}),s.jsx("p",{className:a.message,children:o}),s.jsxs("div",{className:a.actions,children:[s.jsx("button",{className:a.cancelButton,onClick:l,disabled:e,children:c}),s.jsx("button",{className:a.confirmButton,onClick:d,disabled:e,children:e?"...":n})]})]})}):null}export{p as C};
1
+ import{r as u,j as s}from"./index-C_exRd2o.js";import{s as a}from"./ConfirmModal.module-DJksQHBd.js";function p({open:r,title:t,message:o,cancelLabel:c,confirmLabel:n,loading:e=!1,onCancel:l,onConfirm:d}){const i=u.useId();return r?s.jsx("div",{className:a.backdrop,onClick:e?void 0:l,children:s.jsxs("div",{className:a.modal,role:"dialog","aria-modal":"true","aria-labelledby":i,onClick:m=>m.stopPropagation(),children:[s.jsx("h2",{id:i,className:a.title,children:t}),s.jsx("p",{className:a.message,children:o}),s.jsxs("div",{className:a.actions,children:[s.jsx("button",{className:a.cancelButton,onClick:l,disabled:e,children:c}),s.jsx("button",{className:a.confirmButton,onClick:d,disabled:e,children:e?"...":n})]})]})}):null}export{p as C};
@@ -0,0 +1,11 @@
1
+ import{i as te,u as oe,r as d,j as e,f as ie,a as F,D as ce,L as le,M as ae,k as V,e as re,l as de,s as ge}from"./index-C_exRd2o.js";import{I as u}from"./InfoLabel-HLPMIIL4.js";import{P as pe}from"./PageHeader-Cvi0LO4r.js";import{S as ne}from"./StatusBadge-Cf1Ncow3.js";import{T as X}from"./TooltipText-1fJvqtMt.js";import{C as J}from"./ConfirmModal-DJp4ax33.js";import{f as se,u as ue}from"./useLiveUptime-D0TQTjV7.js";import{C as q}from"./copy-d0x3Roiq.js";import"./UiPrimitive-CsV5QE01.js";import"./ConfirmModal.module-DJksQHBd.js";/**
2
+ * @license lucide-react v1.8.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const he=[["path",{d:"M12 8V4H8",key:"hb8ula"}],["rect",{width:"16",height:"12",x:"4",y:"8",rx:"2",key:"enze0r"}],["path",{d:"M2 14h2",key:"vft8re"}],["path",{d:"M20 14h2",key:"4cs60a"}],["path",{d:"M15 13v2",key:"1xurst"}],["path",{d:"M9 13v2",key:"rq6x2g"}]],ye=te("bot",he);/**
7
+ * @license lucide-react v1.8.0 - ISC
8
+ *
9
+ * This source code is licensed under the ISC license.
10
+ * See the LICENSE file in the root directory of this source tree.
11
+ */const me=[["rect",{width:"20",height:"8",x:"2",y:"2",rx:"2",ry:"2",key:"ngkwjq"}],["rect",{width:"20",height:"8",x:"2",y:"14",rx:"2",ry:"2",key:"iecqi9"}],["line",{x1:"6",x2:"6.01",y1:"6",y2:"6",key:"16zg32"}],["line",{x1:"6",x2:"6.01",y1:"18",y2:"18",key:"nzw8ys"}]],xe=te("server",me),_e="_container_1h084_2",Se="_entry_1h084_14",je="_timestamp_1h084_21",ve="_message_1h084_27",ke="_warn_1h084_34",fe="_error_1h084_39",be="_empty_1h084_44",W={container:_e,entry:Se,timestamp:je,message:ve,warn:ke,error:fe,empty:be};function Ce(t){const s=new Date(t);return Number.isNaN(s.getTime())?t:`${String(s.getHours()).padStart(2,"0")}:${String(s.getMinutes()).padStart(2,"0")}`}function Ne({entries:t}){const{t:s}=oe(),n=d.useRef(null);return d.useEffect(()=>{const l=n.current;l&&(l.scrollTop=l.scrollHeight)},[t.length]),e.jsx("div",{ref:n,className:W.container,children:t.length===0?e.jsx("div",{className:W.empty,children:s("connection.log.empty","No events yet")}):t.map((l,i)=>e.jsxs("div",{className:`${W.entry} ${l.type?W[l.type]:""}`,children:[e.jsx("span",{className:W.timestamp,children:Ce(l.timestamp)}),e.jsx("span",{className:W.message,children:l.message})]},i))})}const Q=50;function we(){const t=new Date;return`${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`}function Ie(){const{level:t,status:s,error:n}=ie(),[l,i]=d.useState(null),[y,g]=d.useState(null),[c,w]=d.useState([]),b=d.useRef(null),A=d.useCallback((p,j)=>{w(N=>{const S=[...N,{timestamp:we(),message:p,type:j}];return S.length>Q?S.slice(-Q):S})},[]),m=d.useCallback(async()=>{try{const p=await F.get("/connection-info");i(p)}catch{i(null)}},[]),P=d.useCallback(async()=>{try{const p=await F.get("/api/dashboard/studio-routing");g(p)}catch{g(null)}},[]),I=d.useCallback(async p=>{const j=await F.patch("/api/dashboard/studio-routing",p);return g(j),await m(),j},[m]),M=d.useCallback(async()=>{try{const p=await F.get("/api/dashboard/connection-log");w(p.entries??[])}catch{w([])}},[]),H=d.useCallback(async()=>{await F.post("/api/dashboard/connection-log/clear"),w([])},[]),C=d.useCallback(async p=>{await F.post("/api/dashboard/kill-agent",{instanceId:p}),await m()},[m]);return d.useEffect(()=>{t!=="disconnected"&&s?(m(),P()):g(null),M()},[t,s,m,M,P]),d.useEffect(()=>{const p=new ce;b.current=p,p.connect();const j=p.on("connection",S=>{const h=S;h.status!=="updated"&&h.clientId&&A(`Plugin ${h.status} — ${h.clientId}`,h.status==="disconnected"?"warn":"info"),m(),P()}),N=p.on("mcp_status",S=>{const h=S,z=h.status==="registered"?"registered":"unregistered";A(`MCP ${z} — ${h.aiClientName}`,h.status==="registered"?"info":"warn"),m(),P()});return()=>{j(),N(),p.disconnect(),b.current=null}},[A,m,P]),{status:s,connectionInfo:l,studioRouting:y,connectionLog:c,level:t,error:n,clearConnectionLog:H,killAgent:C,updateStudioRouting:I}}const Le="_page_14kg9_2",Ae="_card_14kg9_11",Pe="_topologyCard_14kg9_19",Be="_topologyDisconnected_14kg9_26",$e="_topologyHeader_14kg9_30",Me="_topologyIntro_14kg9_38",Ee="_topologyNetwork_14kg9_45",Te="_topologyLinks_14kg9_49",He="_topologyLink_14kg9_49",De="_topologyLink_agent_14kg9_66",Ue="_topologyLink_studio_14kg9_70",Oe="_topologyGrid_14kg9_74",Fe="_topologyColumn_14kg9_83",We="_topologyColumnHeader_14kg9_90",ze="_topologyColumnHeaderSpacer_14kg9_101",Ye="_topologyCount_14kg9_105",Ve="_topologyList_14kg9_120",Ge="_topologyListCentered_14kg9_128",qe="_topologyNode_14kg9_132",Re="_topologyNodeTitle_14kg9_140",Ke="_topologyNodeMeta_14kg9_156",Xe="_topologyNodeSubtle_14kg9_157",Je="_topologyState_14kg9_170",Qe="_topologyEmpty_14kg9_183",Ze="_topologyOverflow_14kg9_198",et="_topologyOverflowButton_14kg9_213",tt="_topologyServerColumn_14kg9_236",ot="_topologyServer_14kg9_236",nt="_topologyServerIcon_14kg9_254",st="_topologyServerBody_14kg9_267",it="_topologyServerTitle_14kg9_276",ct="_topologyServerMeta_14kg9_283",lt="_routingSummaryCompact_14kg9_290",at="_disabled_14kg9_298",rt="_cardHeader_14kg9_304",dt="_cardHint_14kg9_317",gt="_clearButton_14kg9_324",pt="_serverGrid_14kg9_348",ut="_statusRow_14kg9_366",ht="_metaItem_14kg9_373",yt="_table_14kg9_380",mt="_tableWrap_14kg9_400",xt="_routingSummary_14kg9_290",_t="_manageLink_14kg9_416",St="_segment_14kg9_442",jt="_segmentActive_14kg9_443",vt="_targetPrimary_14kg9_477",kt="_monoMuted_14kg9_481",ft="_copyIconButton_14kg9_485",bt="_routingBadge_14kg9_510",Ct="_studioStateBadge_14kg9_524",Nt="_studioState_running_14kg9_539",wt="_studioState_paused_14kg9_545",It="_studioState_edit_14kg9_551",Lt="_studioState_unknown_14kg9_557",At="_toggleBtn_14kg9_564",Pt="_disconnected_14kg9_579",Bt="_disconnectedActions_14kg9_596",$t="_btn_14kg9_603",Mt="_activity_active_14kg9_621",Et="_activity_stale_14kg9_622",Tt="_activity_unknown_14kg9_623",Ht="_killBtn_14kg9_647",Dt="_emptyRow_14kg9_671",o={page:Le,card:Ae,topologyCard:Pe,topologyDisconnected:Be,topologyHeader:$e,topologyIntro:Me,topologyNetwork:Ee,topologyLinks:Te,topologyLink:He,topologyLink_agent:De,topologyLink_studio:Ue,topologyGrid:Oe,topologyColumn:Fe,topologyColumnHeader:We,topologyColumnHeaderSpacer:ze,topologyCount:Ye,topologyList:Ve,topologyListCentered:Ge,topologyNode:qe,topologyNodeTitle:Re,topologyNodeMeta:Ke,topologyNodeSubtle:Xe,topologyState:Je,topologyEmpty:Qe,topologyOverflow:Ze,topologyOverflowButton:et,topologyServerColumn:tt,topologyServer:ot,topologyServerIcon:nt,topologyServerBody:st,topologyServerTitle:it,topologyServerMeta:ct,routingSummaryCompact:lt,disabled:at,cardHeader:rt,cardHint:dt,clearButton:gt,serverGrid:pt,statusRow:ut,metaItem:ht,table:yt,tableWrap:mt,routingSummary:xt,manageLink:_t,segment:St,segmentActive:jt,targetPrimary:vt,monoMuted:kt,copyIconButton:ft,routingBadge:bt,studioStateBadge:Ct,studioState_running:Nt,studioState_paused:wt,studioState_edit:It,studioState_unknown:Lt,toggleBtn:At,disconnected:Pt,disconnectedActions:Bt,btn:$t,activity_active:Mt,activity_stale:Et,activity_unknown:Tt,killBtn:Ht,emptyRow:Dt},G=5;function Ut(t){return t?Date.now()-t<3e4?"active":"stale":"unknown"}function Ot(t,s){return t==="active"?s("connection.topology.active","Active"):t==="stale"?s("connection.topology.stale","Stale"):s("connection.topology.unknown","Unknown")}function Z(t){return t.length>10?t.slice(0,10):t}function ee(t,s){return t.replace("{count}",String(s))}function Ft(t,s,n){const l=t.studioState??"unknown",i={edit:s("connection.targets.studioState.edit","Edit"),running:s("connection.targets.studioState.running","Running"),paused:s("connection.targets.studioState.paused","Paused"),unknown:s("connection.targets.studioState.unknown","Unknown")},y=t.studioStateSource==="thread"?s("connection.targets.studioState.source.thread","WEPPY play command"):t.studioStateSource==="pluginConnection"?s("connection.targets.studioState.source.pluginConnection","Studio Play/Test connection"):t.studioStateSource==="runService"?s("connection.targets.studioState.source.runService","Studio RunService"):s("connection.targets.studioState.source.unknown","Unknown source"),g=t.studioStateUpdatedAt?n(t.studioStateUpdatedAt):s("connection.targets.studioState.updatedUnknown","not reported");return{state:l,label:i[l],tooltip:`${y} · ${g}`}}function Wt(t,s){return t.length!==s.length?!1:t.every((n,l)=>{const i=s[l];return i!==void 0&&n.id===i.id&&n.side===i.side&&Math.abs(n.x1-i.x1)<.5&&Math.abs(n.y1-i.y1)<.5&&Math.abs(n.x2-i.x2)<.5&&Math.abs(n.y2-i.y2)<.5})}function f(t,s,n){return{x:s-t.left,y:n-t.top}}function zt(t,s,n,l){if(s.right<=n.left){const g=f(l,s.right,s.top+s.height/2),c=f(l,n.left,n.top+n.height/2);return{id:t,side:"agent",x1:g.x,y1:g.y,x2:c.x,y2:c.y}}if(s.bottom<=n.top){const g=f(l,s.left+s.width/2,s.bottom),c=f(l,n.left+n.width/2,n.top);return{id:t,side:"agent",x1:g.x,y1:g.y,x2:c.x,y2:c.y}}const i=f(l,s.left+s.width/2,s.top),y=f(l,n.left+n.width/2,n.bottom);return{id:t,side:"agent",x1:i.x,y1:i.y,x2:y.x,y2:y.y}}function Yt(t,s,n,l){if(n.right<=s.left){const g=f(l,s.left,s.top+s.height/2),c=f(l,n.right,n.top+n.height/2);return{id:t,side:"studio",x1:g.x,y1:g.y,x2:c.x,y2:c.y}}if(n.bottom<=s.top){const g=f(l,s.left+s.width/2,s.top),c=f(l,n.left+n.width/2,n.bottom);return{id:t,side:"studio",x1:g.x,y1:g.y,x2:c.x,y2:c.y}}const i=f(l,s.left+s.width/2,s.bottom),y=f(l,n.left+n.width/2,n.top);return{id:t,side:"studio",x1:i.x,y1:i.y,x2:y.x,y2:y.y}}function Vt({agents:t,isDisconnected:s,pinnedTargetClientId:n,priorityTarget:l,status:i,studioRoutingMode:y,studioTargets:g,t:c,timeAgo:w,onCopySelector:b,onManageRouting:A}){const[m,P]=d.useState(!1),[I,M]=d.useState(!1),[H,C]=d.useState([]),p=d.useRef(null),j=d.useRef(null),N=d.useRef(new Map),S=d.useRef(new Map),h=y==="pinned"?c("connection.routing.pinned","Manual: Pinned Studio"):c("connection.routing.recentPriority","Automatic: Recent priority"),z=s?"offline":"online",k=d.useMemo(()=>m?t:t.slice(0,G),[t,m]),D=Math.max(0,t.length-k.length),v=d.useMemo(()=>I?g:g.slice(0,G),[g,I]),E=Math.max(0,g.length-v.length),R=[o.topologyList,k.length<=1?o.topologyListCentered:""].filter(Boolean).join(" "),K=[o.topologyList,v.length<=1?o.topologyListCentered:""].filter(Boolean).join(" "),U=d.useCallback(a=>x=>{if(x){N.current.set(a,x);return}N.current.delete(a)},[]),r=d.useCallback(a=>x=>{if(x){S.current.set(a,x);return}S.current.delete(a)},[]),L=d.useCallback(()=>{const a=p.current,x=j.current;if(!a||!x){C([]);return}const _=a.getBoundingClientRect(),B=x.getBoundingClientRect(),O=[];k.forEach($=>{const Y=N.current.get($.instanceId);Y&&O.push(zt(`agent-${$.instanceId}`,Y.getBoundingClientRect(),B,_))}),v.forEach($=>{const Y=S.current.get($.clientId);Y&&O.push(Yt(`studio-${$.clientId}`,Y.getBoundingClientRect(),B,_))}),C($=>Wt($,O)?$:O)},[k,v]);return d.useLayoutEffect(()=>{L();const a=[p.current,j.current,...k.map(_=>N.current.get(_.instanceId)),...v.map(_=>S.current.get(_.clientId))].filter(_=>_!=null);if(window.addEventListener("resize",L),typeof ResizeObserver>"u")return()=>{window.removeEventListener("resize",L)};const x=new ResizeObserver(L);return a.forEach(_=>x.observe(_)),()=>{window.removeEventListener("resize",L),x.disconnect()}},[L,k,v]),e.jsxs("section",{className:`${o.topologyCard} ${s?o.topologyDisconnected:""}`,"aria-label":c("connection.topology.ariaLabel","Connection topology"),children:[e.jsxs("div",{className:o.topologyHeader,children:[e.jsxs("div",{children:[e.jsx("div",{className:o.cardHeader,children:c("connection.topology.title","Connection topology")}),e.jsx("p",{className:o.topologyIntro,children:c("connection.topology.description","Each AI agent connects through its own MCP Adapter to one shared WEPPY Bridge, which keeps Roblox Studio connected.")})]}),e.jsx(le,{to:"/controls?section=studio-routing",className:o.manageLink,onClick:A,children:c("connection.routing.manage","Manage routing")})]}),e.jsxs("div",{className:o.topologyNetwork,ref:p,children:[e.jsx("svg",{"aria-hidden":"true",className:o.topologyLinks,"data-testid":"topology-connection-lines",focusable:"false",children:H.map(a=>e.jsx("line",{className:`${o.topologyLink} ${o[`topologyLink_${a.side}`]}`,"data-side":a.side,vectorEffect:"non-scaling-stroke",x1:a.x1,x2:a.x2,y1:a.y1,y2:a.y2},a.id))}),e.jsxs("div",{className:o.topologyGrid,children:[e.jsxs("div",{className:o.topologyColumn,children:[e.jsxs("div",{className:o.topologyColumnHeader,children:[e.jsx(ye,{size:15,"aria-hidden":"true"}),e.jsx("span",{children:c("connection.agents.title","AI Agents")}),e.jsx("span",{className:o.topologyCount,children:t.length})]}),e.jsxs("div",{className:R,children:[t.length>0?k.map(a=>{const x=Ut(a.lastSeen),_=a.aiClientName??Z(a.instanceId),B=a.lastSeen??a.lastCommandAt??a.connectedAt,O=a.mcpVersion?`${c("connection.topology.adapterRole","MCP Adapter")} v${a.mcpVersion}`:c("connection.topology.adapterRole","MCP Adapter");return e.jsxs("div",{className:o.topologyNode,ref:U(a.instanceId),children:[e.jsxs("div",{className:o.topologyNodeTitle,children:[e.jsx("span",{className:o[`activity_${x}`]}),e.jsx("strong",{children:_}),e.jsx("span",{className:o.topologyState,children:Ot(x,c)})]}),e.jsxs("div",{className:o.topologyNodeMeta,children:[e.jsx("span",{children:O})," ·"," ",c("connection.server.session","Session")," ",Z(a.instanceId)," ·"," ",B?`${c("connection.topology.lastActivity","Last activity")} ${w(B)}`:c("connection.topology.noActivity","No recent activity")]})]},a.instanceId)}):e.jsx("div",{className:o.topologyEmpty,children:c("connection.agents.none","No agents connected")}),t.length>G?e.jsxs("div",{className:o.topologyOverflow,children:[D>0?e.jsx("span",{children:ee(c("connection.topology.moreAgents","+{count} more agents"),D)}):e.jsx("span",{children:c("connection.topology.allAgentsVisible","All agents visible")}),e.jsx("button",{type:"button",className:o.topologyOverflowButton,"aria-label":m?c("connection.topology.showLessAgents","Show less AI agents"):c("connection.topology.showAllAgents","Show all AI agents"),onClick:()=>P(a=>!a),children:m?c("connection.topology.showLess","Show less"):c("connection.topology.showAll","Show all")})]}):null]})]}),e.jsxs("div",{className:o.topologyServerColumn,children:[e.jsx("div",{className:o.topologyColumnHeaderSpacer,"aria-hidden":"true"}),e.jsxs("div",{className:`${o.topologyNode} ${o.topologyServer}`,ref:j,children:[e.jsx("div",{className:o.topologyServerIcon,children:e.jsx(xe,{size:18,"aria-hidden":"true"})}),e.jsxs("div",{className:o.topologyServerBody,children:[e.jsx("div",{className:o.topologyServerTitle,children:c("connection.topology.serverTitle","WEPPY Bridge")}),e.jsx(ne,{status:z}),e.jsxs("div",{className:o.topologyServerMeta,children:[i!=null&&i.version?`v${i.version}`:c("connection.topology.versionUnknown","Version unknown"),i!=null&&i.sessionId?` · ${c("connection.server.session","Session")} ${i.sessionId.slice(0,8)}`:""]}),(i==null?void 0:i.pid)!=null||(i==null?void 0:i.uptime)!=null?e.jsxs("div",{className:o.topologyNodeSubtle,children:[(i==null?void 0:i.pid)!=null?e.jsx("span",{children:`${c("connection.server.pid","PID")} ${i.pid}`}):null,(i==null?void 0:i.pid)!=null&&(i==null?void 0:i.uptime)!=null?" · ":"",(i==null?void 0:i.uptime)!=null?e.jsx("span",{children:`${c("connection.server.uptime","Uptime")} ${se(i.uptime)}`}):null]}):null,e.jsx("div",{className:o.routingSummaryCompact,children:e.jsx("span",{className:o.routingBadge,children:h})})]})]})]}),e.jsxs("div",{className:o.topologyColumn,children:[e.jsxs("div",{className:o.topologyColumnHeader,children:[e.jsx(ae,{size:15,"aria-hidden":"true"}),e.jsx("span",{children:c("connection.targets.title","Studio Targets")}),e.jsx("span",{className:o.topologyCount,children:g.length})]}),e.jsxs("div",{className:K,children:[g.length>0?v.map(a=>{const x=y==="pinned"&&n===a.clientId,_=y==="recentPriority"&&(l==null?void 0:l.clientId)===a.clientId,B=Ft(a,c,w);return e.jsxs("div",{className:o.topologyNode,ref:r(a.clientId),children:[e.jsxs("div",{className:o.topologyNodeTitle,children:[e.jsx("span",{className:o.targetPrimary,children:a.targetAlias}),e.jsx(V,{text:c("connection.targets.copyTargetAlias","Copy Studio ID"),children:e.jsx("button",{type:"button",className:o.copyIconButton,"aria-label":c("connection.targets.copyTargetAlias","Copy Studio ID"),onClick:()=>b(a.targetAlias,"target_alias"),children:e.jsx(q,{size:13,"aria-hidden":"true"})})}),x?e.jsx("span",{className:o.routingBadge,children:c("connection.routing.pinnedBadge","Pinned")}):_?e.jsx("span",{className:o.routingBadge,children:c("connection.routing.priorityBadge","Priority")}):null,e.jsx(V,{text:B.tooltip,children:e.jsx("span",{className:`${o.studioStateBadge} ${o[`studioState_${B.state}`]}`,children:B.label})})]}),e.jsxs("div",{className:o.topologyNodeMeta,children:[e.jsx("span",{children:a.placeName??c("connection.topology.placeUnknown","Place unknown")}),a.placeId!==void 0?` · ${a.placeId}`:""]}),e.jsxs("div",{className:o.topologyNodeSubtle,children:[a.connectionState," · ",c("connection.targets.lastSeen","Last Seen")," ",w(a.lastSeen)]})]},a.clientId)}):e.jsx("div",{className:o.topologyEmpty,children:c("connection.targets.none","No Studio targets connected. Open Roblox Studio and connect WEPPY Plugin.")}),g.length>G?e.jsxs("div",{className:o.topologyOverflow,children:[E>0?e.jsx("span",{children:ee(c("connection.topology.moreStudios","+{count} more studios"),E)}):e.jsx("span",{children:c("connection.topology.allStudiosVisible","All studios visible")}),e.jsx("button",{type:"button",className:o.topologyOverflowButton,"aria-label":I?c("connection.topology.showLessStudios","Show less Studio targets"):c("connection.topology.showAllStudios","Show all Studio targets"),onClick:()=>M(a=>!a),children:I?c("connection.topology.showLess","Show less"):c("connection.topology.showAll","Show all")})]}):null]})]})]})]})]})}function T(t,s){const n=Math.max(0,Math.floor((Date.now()-t)/1e3));return n<60?`${n}${s("connection.time.secondsAgo","s ago")}`:n<3600?`${Math.floor(n/60)}${s("connection.time.minutesAgo","m ago")}`:`${Math.floor(n/3600)}${s("connection.time.hoursAgo","h ago")}`}function Gt(t){return t?Date.now()-t<3e4?"active":"stale":"unknown"}function qt(t,s){const n=t.studioState??"unknown",l={edit:s("connection.targets.studioState.edit","Edit"),running:s("connection.targets.studioState.running","Running"),paused:s("connection.targets.studioState.paused","Paused"),unknown:s("connection.targets.studioState.unknown","Unknown")},i=t.studioStateSource==="thread"?s("connection.targets.studioState.source.thread","WEPPY play command"):t.studioStateSource==="pluginConnection"?s("connection.targets.studioState.source.pluginConnection","Studio Play/Test connection"):t.studioStateSource==="runService"?s("connection.targets.studioState.source.runService","Studio RunService"):s("connection.targets.studioState.source.unknown","Unknown source"),y=t.studioStateUpdatedAt?T(t.studioStateUpdatedAt,s):s("connection.targets.studioState.updatedUnknown","not reported"),g=t.playtestMode&&t.playtestMode!=="unknown"?` · ${t.playtestMode}`:"";return{state:n,label:`${l[n]}${g}`,tooltip:`${i} · ${y}`}}function so(){const{t}=oe(),{trackEvent:s}=re(),{status:n,connectionInfo:l,studioRouting:i,connectionLog:y,level:g,clearConnectionLog:c,killAgent:w}=Ie(),{show:b}=de(),[A,m]=d.useState(!0),[P,I]=d.useState(!1),[M,H]=d.useState(!1),[C,p]=d.useState(null),[j,N]=d.useState(!1),S=ue(n==null?void 0:n.uptime),h=g==="disconnected",z=h?"offline":"online",k=(i==null?void 0:i.studioRoutingMode)??(n==null?void 0:n.studioRoutingMode)??"recentPriority",D=(i==null?void 0:i.pinnedTargetClientId)??(n==null?void 0:n.pinnedTargetClientId)??null,v=ge((i==null?void 0:i.targets)??(n==null?void 0:n.pluginClients)??[],k,D),E=(i==null?void 0:i.priorityTarget)??v[0],R=async()=>{if(C){N(!0);try{await w(C.instanceId),b(t("connection.agents.killed","Agent killed"),"success"),p(null)}catch{b(t("connection.agents.killFailed","Failed to kill agent"),"error")}finally{N(!1)}}},K=async()=>{H(!0);try{await c(),b(t("toast.clearSuccess","Cleared successfully"),"success"),I(!1)}catch{b(t("toast.clearFailed","Failed to clear data"),"error")}finally{H(!1)}},U=async(r,L)=>{try{await navigator.clipboard.writeText(r),b(t("connection.targets.copied","Copied value"),"success"),s("dashboard_click_event",{click_target:`connection_copy_${L}`,page:"connection"})}catch{b(t("connection.targets.copyFailed","Failed to copy value"),"error")}};return e.jsxs("div",{className:o.page,children:[e.jsx(pe,{title:t("page.connection.title","Connection"),description:t("page.connection.description","Inspect WEPPY Bridge, MCP Adapter, Studio Plugin, and connection log status."),helpTopicId:"connection",helpState:{connectionLevel:g}}),e.jsx(Vt,{agents:(l==null?void 0:l.mcpInstances)??[],isDisconnected:h,pinnedTargetClientId:D,priorityTarget:E,status:n??null,studioRoutingMode:k,studioTargets:v,t,timeAgo:r=>T(r,t),onCopySelector:U,onManageRouting:()=>s("dashboard_click_event",{click_target:"connection_manage_routing",page:"connection"})}),e.jsxs("div",{className:o.card,children:[e.jsx("div",{className:o.cardHeader,children:t("connection.server.title","Bridge Status")}),h?e.jsxs("div",{className:o.disconnected,children:[e.jsx("h3",{children:t("level.l0.title")}),e.jsx("p",{children:t("level.l0.message")}),e.jsx("p",{children:t("common.reconnecting")}),e.jsxs("div",{className:o.disconnectedActions,children:[e.jsx("button",{className:o.btn,onClick:()=>window.location.reload(),children:t("connection.reconnect","Reconnect")}),e.jsx("button",{className:o.btn,onClick:()=>{window.location.hash="#/settings"},children:t("connection.checkSettings","Check Settings")})]})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:o.statusRow,children:e.jsx(ne,{status:z})}),e.jsxs("dl",{className:o.serverGrid,children:[(n==null?void 0:n.version)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(u,{label:t("connection.server.version","Version"),tooltip:t("connection.server.version.tooltip","WEPPY Bridge runtime version")})}),e.jsx("dd",{children:e.jsx(X,{text:t("connection.server.version.tooltip","WEPPY Bridge runtime version"),children:`v${n.version}`})})]}),(n==null?void 0:n.pid)!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(u,{label:t("connection.server.pid","PID"),tooltip:t("connection.server.pid.tooltip","Operating system process identifier")})}),e.jsx("dd",{children:n.pid})]}),(n==null?void 0:n.uptime)!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(u,{label:t("connection.server.uptime","Uptime"),tooltip:t("connection.server.uptime.tooltip","Time elapsed since the WEPPY Bridge started")})}),e.jsx("dd",{children:se(S??n.uptime)})]}),(n==null?void 0:n.sessionId)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(u,{label:t("connection.server.session","Session"),tooltip:t("connection.server.session.tooltip","Current WEPPY Bridge session identifier")})}),e.jsx("dd",{children:n.sessionId.slice(0,8)})]}),(l==null?void 0:l.serverExecutable)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(u,{label:t("connection.server.exec","Exec"),tooltip:t("connection.server.exec.tooltip","Executable path used to launch the WEPPY Bridge")})}),e.jsx("dd",{children:l.serverExecutable})]})]})]})]}),e.jsxs("div",{className:`${o.card} ${h?o.disabled:""}`,children:[e.jsxs("div",{className:o.cardHeader,children:[e.jsxs("span",{children:[t("connection.agents.title","AI Agents")," ","(",(l==null?void 0:l.mcpInstanceCount)??0,")"]}),e.jsx("button",{className:o.toggleBtn,onClick:()=>m(r=>!r),"aria-label":A?t("common.collapse","Collapse"):t("common.expand","Expand"),children:A?"▾":"▸"})]}),A&&e.jsxs("table",{className:o.table,children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:t("connection.agents.name","Agent")}),e.jsx("th",{children:e.jsx(u,{label:t("connection.agents.version","Version"),tooltip:t("connection.agents.version.tooltip","MCP Adapter package version for this agent session")})}),e.jsx("th",{children:e.jsx(u,{label:t("connection.server.pid","PID"),tooltip:t("connection.server.pid.tooltip","Operating system process identifier")})}),e.jsx("th",{children:e.jsx(u,{label:t("connection.agents.projectRoot","Project Root"),tooltip:t("connection.agents.projectRoot.tooltip","Authoritative project root for sync ownership")})}),e.jsx("th",{children:t("connection.agents.connected","Connected")}),e.jsx("th",{children:e.jsx(u,{label:t("connection.agents.lastSeen","Last Seen"),tooltip:t("connection.agents.lastSeen.tooltip","Most recent heartbeat or activity from this agent")})}),e.jsx("th",{children:e.jsx(u,{label:t("connection.agents.lastCommand","Last Command"),tooltip:t("connection.agents.lastCommand.tooltip","Most recent tool call executed by this agent")})}),e.jsx("th",{})]})}),e.jsx("tbody",{children:l!=null&&l.mcpInstances&&l.mcpInstances.length>0?l.mcpInstances.map(r=>e.jsxs("tr",{children:[e.jsxs("td",{children:[e.jsx("span",{className:o[`activity_${Gt(r.lastSeen)}`]}),r.aiClientName??t("connection.agents.unknown","Unknown")]}),e.jsx("td",{children:r.mcpVersion??"-"}),e.jsx("td",{children:r.pid}),e.jsx("td",{children:r.projectRoot??r.cwd??t("connection.agents.projectRoot.unresolved","Unresolved")}),e.jsx("td",{children:T(r.connectedAt,t)}),e.jsx("td",{children:r.lastSeen?T(r.lastSeen,t):"-"}),e.jsx("td",{children:r.lastCommandAt?T(r.lastCommandAt,t):"-"}),e.jsx("td",{children:!r.isServer&&e.jsx("button",{className:o.killBtn,onClick:()=>{s("dashboard_click_event",{click_target:"connection_kill_agent",page:"connection"}),p({instanceId:r.instanceId,name:r.aiClientName??r.instanceId.slice(0,8)})},children:t("connection.agents.kill","Kill")})})]},r.instanceId)):e.jsx("tr",{children:e.jsx("td",{colSpan:8,className:o.emptyRow,children:t("connection.agents.none","No agents connected")})})})]})]}),e.jsxs("div",{className:`${o.card} ${h?o.disabled:""}`,children:[e.jsxs("div",{className:o.cardHeader,children:[t("connection.targets.title","Studio Targets")," ","(",v.length,")"]}),e.jsx("p",{className:o.cardHint,children:t("connection.targets.help","When multiple Studio windows are connected, tell the agent to use Studio ID studio-1 to choose one.")}),e.jsx("div",{className:o.tableWrap,children:e.jsxs("table",{className:o.table,children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:e.jsx(u,{label:t("connection.targets.target","Studio ID"),tooltip:t("connection.targets.target.tooltip","Short name for this Roblox Studio window")})}),e.jsx("th",{children:t("connection.targets.place","Place")}),e.jsx("th",{children:e.jsx(u,{label:t("connection.targets.placeId","Place ID"),tooltip:t("connection.targets.placeId.tooltip","Roblox Place ID for this Studio window")})}),e.jsx("th",{children:e.jsx(u,{label:t("connection.targets.clientId","Connection ID"),tooltip:t("connection.targets.clientId.tooltip","Full connection ID for diagnostics. Usually use Studio ID instead.")})}),e.jsx("th",{children:e.jsx(u,{label:t("connection.targets.studioState","Studio State"),tooltip:t("connection.targets.studioState.tooltip","Current edit/play runtime state reported by this Studio window")})}),e.jsx("th",{children:e.jsx(u,{label:t("connection.targets.session","Session"),tooltip:t("connection.targets.session.tooltip","Command channel state for this Studio target")})}),e.jsx("th",{children:e.jsx(u,{label:t("connection.targets.lastUsed","Last Used"),tooltip:t("connection.targets.lastUsed.tooltip","Most recent plugin-route request routed to this Studio target")})}),e.jsx("th",{children:e.jsx(u,{label:t("connection.targets.lastSeen","Last Seen"),tooltip:t("connection.targets.lastSeen.tooltip","Most recent heartbeat received from this Studio target")})}),e.jsx("th",{children:e.jsx(u,{label:t("connection.targets.version","Version"),tooltip:t("connection.targets.version.tooltip","Installed plugin version reported by Studio")})}),e.jsx("th",{children:e.jsx(u,{label:t("connection.targets.routing","Routing"),tooltip:t("connection.targets.routing.tooltip","Routing priority for requests without a named Studio target")})}),e.jsx("th",{children:e.jsx(u,{label:t("connection.targets.inFlight","In Flight"),tooltip:t("connection.targets.inFlight.tooltip","Active command request currently routed to this Studio target")})})]})}),e.jsx("tbody",{children:v.length>0?v.map(r=>{const L=r.clientId.slice(0,10),a=qt(r,t);return e.jsxs("tr",{children:[e.jsxs("td",{children:[e.jsx("span",{className:o.monoMuted,title:r.clientId,children:r.targetAlias}),e.jsx(V,{text:t("connection.targets.copyTargetAlias","Copy Studio ID"),children:e.jsx("button",{type:"button",className:o.copyIconButton,"aria-label":t("connection.targets.copyTargetAlias","Copy Studio ID"),onClick:()=>U(r.targetAlias,"target_alias"),children:e.jsx(q,{size:13,"aria-hidden":"true"})})})]}),e.jsx("td",{children:e.jsx("span",{className:o.targetPrimary,children:r.placeName??"-"})}),e.jsxs("td",{children:[r.placeId??"-",r.placeId!==void 0?e.jsx(V,{text:t("connection.targets.copyPlaceId","Copy Place ID"),children:e.jsx("button",{type:"button",className:o.copyIconButton,"aria-label":t("connection.targets.copyPlaceId","Copy Place ID"),onClick:()=>U(String(r.placeId),"place_id"),children:e.jsx(q,{size:13,"aria-hidden":"true"})})}):null]}),e.jsxs("td",{children:[e.jsx("span",{className:o.monoMuted,title:r.clientId,children:L}),e.jsx(V,{text:t("connection.targets.copyClientId","Copy Connection ID"),children:e.jsx("button",{type:"button",className:o.copyIconButton,"aria-label":t("connection.targets.copyClientId","Copy Connection ID"),onClick:()=>U(r.clientId,"client_id"),children:e.jsx(q,{size:13,"aria-hidden":"true"})})})]}),e.jsx("td",{children:e.jsx(X,{text:a.tooltip,children:e.jsx("span",{className:`${o.studioStateBadge} ${o[`studioState_${a.state}`]}`,children:a.label})})}),e.jsx("td",{children:r.connectionState}),e.jsx("td",{children:r.lastRoutedAt?T(r.lastRoutedAt,t):"-"}),e.jsx("td",{children:T(r.lastSeen,t)}),e.jsx("td",{children:r.pluginVersion??"-"}),e.jsx("td",{children:k==="pinned"&&D===r.clientId?e.jsx("span",{className:o.routingBadge,children:t("connection.routing.pinnedBadge","Pinned")}):k==="recentPriority"&&(E==null?void 0:E.clientId)===r.clientId?e.jsx("span",{className:o.routingBadge,children:t("connection.routing.priorityBadge","Priority")}):e.jsx("span",{className:o.monoMuted,children:"-"})}),e.jsx("td",{children:r.inFlightRequestId?r.inFlightRequestId.slice(0,8):"-"})]},r.clientId)}):e.jsx("tr",{children:e.jsx("td",{colSpan:11,className:o.emptyRow,children:t("connection.targets.none","No Studio targets connected. Open Roblox Studio and connect WEPPY Plugin.")})})})]})})]}),e.jsxs("div",{className:`${o.card} ${h?o.disabled:""}`,children:[e.jsxs("div",{className:o.cardHeader,children:[e.jsx("span",{children:t("connection.log.title","Connection Log")}),e.jsx("button",{className:o.clearButton,onClick:()=>{s("dashboard_click_event",{click_target:"connection_clear_log",page:"connection"}),I(!0)},children:t("common.clear","Clear")})]}),e.jsx(Ne,{entries:y})]}),e.jsx(J,{open:P,title:t("connection.clear.title","Clear connection log?"),message:t("connection.clear.message","This permanently removes the stored connection log for the current project."),cancelLabel:t("common.cancel","Cancel"),confirmLabel:t("common.clear","Clear"),loading:M,onCancel:()=>!M&&I(!1),onConfirm:K}),e.jsx(J,{open:!!C,title:t("connection.agents.kill.title","Kill agent?"),message:`"${C==null?void 0:C.name}" 프로세스를 강제 종료합니다. 해당 에이전트의 진행 중인 작업이 중단됩니다.`,cancelLabel:t("common.cancel","Cancel"),confirmLabel:t("connection.agents.kill","Kill"),loading:j,onCancel:()=>!j&&p(null),onConfirm:R})]})}export{so as Component};
@@ -1,4 +1,4 @@
1
- import{i as K,u as P,j as e,f as q,l as z,d as k,r as l,v as Z,w as J,x as ee,a as U,s as te,y as ne,k as D,N as oe}from"./index-B1MZBjK4.js";import{D as Q,P as ae}from"./PageHeader-DezmLDg1.js";import{I as T}from"./InfoLabel-Cc4MKAYc.js";import{s as j}from"./ConfirmModal.module-DJksQHBd.js";import{T as F}from"./TooltipText-CMx5IM6p.js";import{s as t,u as ie}from"./useSettings-BGSD8gFB.js";import{C as B}from"./copy-BCrOOq8E.js";import"./UiPrimitive-ojecpNs1.js";/**
1
+ import{i as K,u as P,j as e,f as q,l as z,d as k,r as l,v as Z,w as J,x as ee,a as U,s as te,y as ne,k as D,N as oe}from"./index-C_exRd2o.js";import{D as Q,P as ae}from"./PageHeader-Cvi0LO4r.js";import{I as T}from"./InfoLabel-HLPMIIL4.js";import{s as j}from"./ConfirmModal.module-DJksQHBd.js";import{T as F}from"./TooltipText-1fJvqtMt.js";import{s as t,u as ie}from"./useSettings-DlZqZGnP.js";import{C as B}from"./copy-d0x3Roiq.js";import"./UiPrimitive-CsV5QE01.js";/**
2
2
  * @license lucide-react v1.8.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{u as h,r as f,j as a,g as _}from"./index-B1MZBjK4.js";import{B as x}from"./UiPrimitive-ojecpNs1.js";const j="_scope_1kz7c_1",m="_main_1kz7c_13",k="_label_1kz7c_20",I="_selectorLabel_1kz7c_28",w="_placeSelect_1kz7c_35",z="_name_1kz7c_48",A="_id_1kz7c_59",L="_scopeBadge_1kz7c_66",y="_copy_1kz7c_70",E="_note_1kz7c_82",n={scope:j,main:m,label:k,selectorLabel:I,placeSelect:w,name:z,id:A,scopeBadge:L,copy:y,note:E};function d(e,l){return l===null?null:e.places.find(c=>c.placeId===l)??null}function S(e){var l;return e.lastActivePlaceId!==null?e.lastActivePlaceId:((l=e.places[0])==null?void 0:l.placeId)??null}function B(e){return e.pluginConnected&&e.activePlaceId!==null?e.activePlaceId:S(e)}function U(e,l){if(e.pluginConnected&&e.activePlaceId!==null){const o=d(e,e.activePlaceId);return{label:l("placeScope.current.label","Current Place"),placeId:e.activePlaceId,placeName:e.activePlaceName??(o==null?void 0:o.placeName)??l("placeScope.unknownPlace","Unknown place"),badge:l("placeScope.live","Live"),live:!0,note:null}}const c=S(e),s=d(e,c);if(c!==null){const o=c===e.lastActivePlaceId?e.lastActivePlaceName:null;return{label:l("placeScope.lastActive.label","Last Active Place"),placeId:c,placeName:o??(s==null?void 0:s.placeName)??l("placeScope.unknownPlace","Unknown place"),badge:l("placeScope.pluginRequired","Plugin required"),live:!1,note:l("placeScope.pluginRequired.note","Connect WEPPY Plugin to confirm the live active place.")}}return{label:l("placeScope.noPlace.label","Place scope"),placeId:null,placeName:l("placeScope.noPlace.value","No place data available yet"),badge:l("placeScope.noPlace.badge","No place"),live:!1,note:l("placeScope.noPlace.note","Connect WEPPY Plugin and sync a place to create place-scoped data.")}}function q(e,l,c){const s=typeof l=="number"?d(e,l):null,o=B(e),t=(s==null?void 0:s.placeId)??o,r=d(e,t);if(t===null)return{label:c("placeScope.noPlace.label","Place scope"),placeId:null,placeName:c("placeScope.noPlace.value","No place data available yet"),badge:c("placeScope.noPlace.badge","No place"),live:!1,note:c("placeScope.noPlace.note","Connect WEPPY Plugin and sync a place to create place-scoped data.")};const u=e.pluginConnected&&e.activePlaceId===t,b=t===e.lastActivePlaceId?e.lastActivePlaceName:null;return{label:u?c("placeScope.current.label","Current Place"):c("placeScope.selected.label","Selected Place"),placeId:t,placeName:(r==null?void 0:r.placeName)??b??c("placeScope.unknownPlace","Unknown place"),badge:u?c("placeScope.live","Live"):c("placeScope.stored","Stored"),live:u,note:u?null:c("placeScope.selected.note","Showing stored data only. Studio routing is unchanged.")}}function F(e,l){switch(e){case"sync":return l("placeScope.surface.sync","Sync status and logs use this place.");case"changelog":return l("placeScope.surface.changelog","Changelog sessions use this place.");case"playtest":return l("placeScope.surface.playtest","Playtest reports use this place.");case"uiStudio":return l("placeScope.surface.uiStudio","UI captures and change history use this place.");case"tools":return l("placeScope.surface.tools","Tool history and statistics use this place.")}}function W({surface:e,selectable:l=!1,selectedPlaceId:c=null,onSelectedPlaceIdChange:s}){const{t:o}=h(),[t,r]=f.useState(null),[u,b]=f.useState(!0);if(f.useEffect(()=>{let i=!1;async function v(){try{const g=await _();i||r(g)}catch{i||r(null)}finally{i||b(!1)}}return v(),()=>{i=!0}},[]),f.useEffect(()=>{!l||!t||typeof c!="number"||d(t,c)||s==null||s(null)},[s,l,c,t]),u)return a.jsx("div",{className:n.scope,"aria-live":"polite",children:a.jsx("span",{className:n.label,children:o("placeScope.loading","Loading place scope...")})});if(!t)return a.jsx("div",{className:n.scope,"aria-live":"polite",children:a.jsx("span",{className:n.label,children:o("placeScope.unavailable","Place scope unavailable")})});const p=l?q(t,c,o):U(t,o),N=typeof p.placeId=="number"?String(p.placeId):"",P=l&&t.places.length>0;return a.jsxs("div",{className:n.scope,"aria-live":"polite",children:[a.jsxs("div",{className:n.main,children:[P?a.jsxs(a.Fragment,{children:[a.jsxs("label",{className:n.selectorLabel,children:[a.jsx("span",{className:n.label,children:o("placeScope.selector.label","Place data")}),a.jsx("select",{className:n.placeSelect,value:N,onChange:i=>{const v=Number.parseInt(i.currentTarget.value,10);s==null||s(Number.isInteger(v)?v:null)},children:t.places.map(i=>a.jsxs("option",{value:i.placeId,children:[i.placeName," (",i.placeId,")"]},i.placeId))})]}),a.jsx("span",{className:n.label,children:p.label}),a.jsx("span",{className:n.name,children:p.placeName})]}):a.jsxs(a.Fragment,{children:[a.jsx("span",{className:n.label,children:p.label}),a.jsx("span",{className:n.name,children:p.placeName})]}),p.placeId!==null?a.jsx("span",{className:n.id,children:p.placeId}):null,a.jsx(x,{variant:p.live?"success":"warning",shape:"pill",className:n.scopeBadge,children:p.badge})]}),a.jsxs("div",{className:n.copy,children:[a.jsx("span",{children:F(e,o)}),p.note?a.jsx("span",{className:n.note,children:p.note}):null]})]})}export{W as C};
1
+ import{u as h,r as f,j as a,g as _}from"./index-C_exRd2o.js";import{B as x}from"./UiPrimitive-CsV5QE01.js";const j="_scope_1kz7c_1",m="_main_1kz7c_13",k="_label_1kz7c_20",I="_selectorLabel_1kz7c_28",w="_placeSelect_1kz7c_35",z="_name_1kz7c_48",A="_id_1kz7c_59",L="_scopeBadge_1kz7c_66",y="_copy_1kz7c_70",E="_note_1kz7c_82",n={scope:j,main:m,label:k,selectorLabel:I,placeSelect:w,name:z,id:A,scopeBadge:L,copy:y,note:E};function d(e,l){return l===null?null:e.places.find(c=>c.placeId===l)??null}function S(e){var l;return e.lastActivePlaceId!==null?e.lastActivePlaceId:((l=e.places[0])==null?void 0:l.placeId)??null}function B(e){return e.pluginConnected&&e.activePlaceId!==null?e.activePlaceId:S(e)}function U(e,l){if(e.pluginConnected&&e.activePlaceId!==null){const o=d(e,e.activePlaceId);return{label:l("placeScope.current.label","Current Place"),placeId:e.activePlaceId,placeName:e.activePlaceName??(o==null?void 0:o.placeName)??l("placeScope.unknownPlace","Unknown place"),badge:l("placeScope.live","Live"),live:!0,note:null}}const c=S(e),s=d(e,c);if(c!==null){const o=c===e.lastActivePlaceId?e.lastActivePlaceName:null;return{label:l("placeScope.lastActive.label","Last Active Place"),placeId:c,placeName:o??(s==null?void 0:s.placeName)??l("placeScope.unknownPlace","Unknown place"),badge:l("placeScope.pluginRequired","Plugin required"),live:!1,note:l("placeScope.pluginRequired.note","Connect WEPPY Plugin to confirm the live active place.")}}return{label:l("placeScope.noPlace.label","Place scope"),placeId:null,placeName:l("placeScope.noPlace.value","No place data available yet"),badge:l("placeScope.noPlace.badge","No place"),live:!1,note:l("placeScope.noPlace.note","Connect WEPPY Plugin and sync a place to create place-scoped data.")}}function q(e,l,c){const s=typeof l=="number"?d(e,l):null,o=B(e),t=(s==null?void 0:s.placeId)??o,r=d(e,t);if(t===null)return{label:c("placeScope.noPlace.label","Place scope"),placeId:null,placeName:c("placeScope.noPlace.value","No place data available yet"),badge:c("placeScope.noPlace.badge","No place"),live:!1,note:c("placeScope.noPlace.note","Connect WEPPY Plugin and sync a place to create place-scoped data.")};const u=e.pluginConnected&&e.activePlaceId===t,b=t===e.lastActivePlaceId?e.lastActivePlaceName:null;return{label:u?c("placeScope.current.label","Current Place"):c("placeScope.selected.label","Selected Place"),placeId:t,placeName:(r==null?void 0:r.placeName)??b??c("placeScope.unknownPlace","Unknown place"),badge:u?c("placeScope.live","Live"):c("placeScope.stored","Stored"),live:u,note:u?null:c("placeScope.selected.note","Showing stored data only. Studio routing is unchanged.")}}function F(e,l){switch(e){case"sync":return l("placeScope.surface.sync","Sync status and logs use this place.");case"changelog":return l("placeScope.surface.changelog","Changelog sessions use this place.");case"playtest":return l("placeScope.surface.playtest","Playtest reports use this place.");case"uiStudio":return l("placeScope.surface.uiStudio","UI captures and change history use this place.");case"tools":return l("placeScope.surface.tools","Tool history and statistics use this place.")}}function W({surface:e,selectable:l=!1,selectedPlaceId:c=null,onSelectedPlaceIdChange:s}){const{t:o}=h(),[t,r]=f.useState(null),[u,b]=f.useState(!0);if(f.useEffect(()=>{let i=!1;async function v(){try{const g=await _();i||r(g)}catch{i||r(null)}finally{i||b(!1)}}return v(),()=>{i=!0}},[]),f.useEffect(()=>{!l||!t||typeof c!="number"||d(t,c)||s==null||s(null)},[s,l,c,t]),u)return a.jsx("div",{className:n.scope,"aria-live":"polite",children:a.jsx("span",{className:n.label,children:o("placeScope.loading","Loading place scope...")})});if(!t)return a.jsx("div",{className:n.scope,"aria-live":"polite",children:a.jsx("span",{className:n.label,children:o("placeScope.unavailable","Place scope unavailable")})});const p=l?q(t,c,o):U(t,o),N=typeof p.placeId=="number"?String(p.placeId):"",P=l&&t.places.length>0;return a.jsxs("div",{className:n.scope,"aria-live":"polite",children:[a.jsxs("div",{className:n.main,children:[P?a.jsxs(a.Fragment,{children:[a.jsxs("label",{className:n.selectorLabel,children:[a.jsx("span",{className:n.label,children:o("placeScope.selector.label","Place data")}),a.jsx("select",{className:n.placeSelect,value:N,onChange:i=>{const v=Number.parseInt(i.currentTarget.value,10);s==null||s(Number.isInteger(v)?v:null)},children:t.places.map(i=>a.jsxs("option",{value:i.placeId,children:[i.placeName," (",i.placeId,")"]},i.placeId))})]}),a.jsx("span",{className:n.label,children:p.label}),a.jsx("span",{className:n.name,children:p.placeName})]}):a.jsxs(a.Fragment,{children:[a.jsx("span",{className:n.label,children:p.label}),a.jsx("span",{className:n.name,children:p.placeName})]}),p.placeId!==null?a.jsx("span",{className:n.id,children:p.placeId}):null,a.jsx(x,{variant:p.live?"success":"warning",shape:"pill",className:n.scopeBadge,children:p.badge})]}),a.jsxs("div",{className:n.copy,children:[a.jsx("span",{children:F(e,o)}),p.note?a.jsx("span",{className:n.note,children:p.note}):null]})]})}export{W as C};
@@ -1,4 +1,4 @@
1
- import{u as _,r as x,j as e}from"./index-B1MZBjK4.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-C_exRd2o.js";const N="_container_uv8oc_2",j="_header_uv8oc_10",v="_modeBtn_uv8oc_18",g="_modeBtnActive_uv8oc_33",w="_unifiedView_uv8oc_40",L="_diffLine_uv8oc_46",b="_lineNum_uv8oc_55",C="_lineContent_uv8oc_64",S="_lineAdded_uv8oc_68",V="_lineRemoved_uv8oc_73",B="_lineContext_uv8oc_78",$="_sideBySide_uv8oc_83",A="_sidePane_uv8oc_90",P="_sideLabel_uv8oc_100",R="_sideContent_uv8oc_112",D="_empty_uv8oc_117",s={container:N,header:j,modeBtn:v,modeBtnActive:g,unifiedView:w,diffLine:L,lineNum:b,lineContent:C,lineAdded:S,lineRemoved:V,lineContext:B,sideBySide:$,sidePane:A,sideLabel:P,sideContent:R,empty:D};function k(n,i){const l=n.split(`
2
2
  `),d=i.split(`
3
3
  `),a=[],f=Math.max(l.length,d.length);let t=0,r=0;for(;(t<l.length||r<d.length)&&(t<l.length&&r<d.length?l[t]===d[r]?(a.push({type:"context",content:l[t],lineNum:r+1}),t++,r++):(a.push({type:"removed",content:l[t],lineNum:t+1}),t++,t<l.length&&l[t]===d[r]?(a.push({type:"added",content:d[r],lineNum:r+1}),r++):r<d.length&&(a.push({type:"added",content:d[r],lineNum:r+1}),r++)):t<l.length?(a.push({type:"removed",content:l[t],lineNum:t+1}),t++):r<d.length&&(a.push({type:"added",content:d[r],lineNum:r+1}),r++),!(a.length>f*3)););return a}function O({before:n,after:i}){const{t:l}=_(),[d,a]=x.useState("unified"),f=typeof n=="string"?n:n!=null?JSON.stringify(n,null,2):"",t=typeof i=="string"?i:i!=null?JSON.stringify(i,null,2):"",r=x.useMemo(()=>k(f,t),[f,t]);if(!f&&!t)return e.jsx("div",{className:s.container,children:e.jsx("div",{className:s.empty,children:l("changelog.diff.empty","No diff available")})});if(!f&&t){const c=t.split(`
4
4
  `);return e.jsx("div",{className:s.container,children:e.jsx("div",{className:s.unifiedView,children:c.map((u,m)=>e.jsxs("div",{className:`${s.diffLine} ${s.lineAdded}`,children:[e.jsx("span",{className:s.lineNum,children:m+1}),e.jsxs("span",{className:s.lineContent,children:["+ ",u]})]},m))})})}return e.jsxs("div",{className:s.container,children:[e.jsxs("div",{className:s.header,children:[e.jsx("button",{className:`${s.modeBtn} ${d==="unified"?s.modeBtnActive:""}`,onClick:()=>a("unified"),children:l("changelog.diff.unified","Unified")}),e.jsx("button",{className:`${s.modeBtn} ${d==="side-by-side"?s.modeBtnActive:""}`,onClick:()=>a("side-by-side"),children:l("changelog.diff.sideBySide","Side by Side")})]}),d==="unified"?e.jsx("div",{className:s.unifiedView,children:r.map((c,u)=>e.jsxs("div",{className:`${s.diffLine} ${c.type==="added"?s.lineAdded:c.type==="removed"?s.lineRemoved:s.lineContext}`,children:[e.jsx("span",{className:s.lineNum,children:c.lineNum??""}),e.jsxs("span",{className:s.lineContent,children:[c.type==="added"?"+ ":c.type==="removed"?"- ":" ",c.content]})]},u))}):e.jsxs("div",{className:s.sideBySide,children:[e.jsxs("div",{className:s.sidePane,children:[e.jsx("div",{className:s.sideLabel,children:l("changelog.diff.before","Before")}),e.jsx("div",{className:s.sideContent,children:f.split(`
@@ -1 +1 @@
1
- import{j as r,k as e}from"./index-B1MZBjK4.js";function s({label:t,tooltip:o}){return r.jsx(e,{text:o,children:t})}export{s as I};
1
+ import{j as r,k as e}from"./index-C_exRd2o.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 t,u as R,r as v,f as L,h as F,a as M,D as V}from"./index-B1MZBjK4.js";import{I as A}from"./InfoLabel-Cc4MKAYc.js";import{P as U}from"./PageHeader-DezmLDg1.js";import{S as z}from"./StatusBadge-C3ARQLqC.js";import{T as O}from"./TooltipText-CMx5IM6p.js";import{G as X}from"./GameChangeDetail-3hQlAqDP.js";import{u as q,f as J}from"./useLiveUptime-fm3oNIW5.js";import"./UiPrimitive-ojecpNs1.js";const K="_page_1xgxh_2",Q="_card_1xgxh_10",W="_cardHeader_1xgxh_17",Y="_disconnectCard_1xgxh_28",Z="_disconnectIcon_1xgxh_36",ee="_disconnectTitle_1xgxh_41",te="_disconnectMessage_1xgxh_48",se="_reconnectGuide_1xgxh_55",ne="_guideStep_1xgxh_64",ie="_stepNumber_1xgxh_72",ce="_reconnectIndicator_1xgxh_88",re="_reconnectDot_1xgxh_98",ae="_pulse_1xgxh_1",oe="_disconnectActions_1xgxh_112",le="_btn_1xgxh_118",de="_btnSecondary_1xgxh_134",me="_metricRow_1xgxh_152",ge="_metricGrid_1xgxh_158",he="_metricCard_1xgxh_164",xe="_metric_ok_1xgxh_174",ue="_metric_warn_1xgxh_179",ve="_metric_error_1xgxh_184",_e="_metricHeader_1xgxh_189",pe="_metricIcon_1xgxh_200",fe="_metricTitle_1xgxh_204",Ce="_metricValue_1xgxh_208",je="_metricSubtitle_1xgxh_215",we="_guideCard_1xgxh_225",Ne="_guideTitle_1xgxh_232",ye="_checklist_1xgxh_239",Te="_feedEmpty_1xgxh_263",Se="_feedList_1xgxh_270",Ie="_feedItem_1xgxh_278",be="_feedTime_1xgxh_291",ke="_feedIcon_1xgxh_298",Me="_feedSummary_1xgxh_304",De="_feedText_1xgxh_313",Be="_feedContext_1xgxh_321",He="_feedItemClickable_1xgxh_330",Ee="_feedChevron_1xgxh_338",Pe="_feedDetail_1xgxh_347",$e="_feedDetailPre_1xgxh_356",Re="_feedDetailText_1xgxh_365",Ge="_changelogSummary_1xgxh_372",Le="_changeTag_1xgxh_381",Fe="_tierBar_1xgxh_393",Ve="_tierBarTrack_1xgxh_399",Ae="_tierBarFillBasic_1xgxh_407",Ue="_tierBarFillPro_1xgxh_412",ze="_tierLabels_1xgxh_417",s={page:K,card:Q,cardHeader:W,disconnectCard:Y,disconnectIcon:Z,disconnectTitle:ee,disconnectMessage:te,reconnectGuide:se,guideStep:ne,stepNumber:ie,reconnectIndicator:ce,reconnectDot:re,pulse:ae,disconnectActions:oe,btn:le,btnSecondary:de,metricRow:me,metricGrid:ge,metricCard:he,metric_ok:xe,metric_warn:ue,metric_error:ve,metricHeader:_e,metricIcon:pe,metricTitle:fe,metricValue:Ce,metricSubtitle:je,guideCard:we,guideTitle:Ne,checklist:ye,feedEmpty:Te,feedList:Se,feedItem:Ie,feedTime:be,feedIcon:ke,feedSummary:Me,feedText:De,feedContext:Be,feedItemClickable:He,feedChevron:Ee,feedDetail:Pe,feedDetailPre:$e,feedDetailText:Re,changelogSummary:Ge,changeTag:Le,tierBar:Fe,tierBarTrack:Ve,tierBarFillBasic:Ae,tierBarFillPro:Ue,tierLabels:ze};function N({title:e,value:i,icon:c,subtitle:r,status:a,children:n}){const l=a?s[`metric_${a}`]:"";return t.jsxs("div",{className:`${s.metricCard} ${l}`,children:[t.jsxs("div",{className:s.metricHeader,children:[c&&t.jsx("span",{className:s.metricIcon,children:c}),t.jsx("span",{className:s.metricTitle,children:e})]}),t.jsx("div",{className:s.metricValue,children:i}),r&&t.jsx("div",{className:s.metricSubtitle,children:r}),n]})}function Oe(e){var c,r;const i=e==null?void 0:e.contextSummary;return(i==null?void 0:i.intent)??((r=(c=i==null?void 0:i.affectedAreas)==null?void 0:c[0])==null?void 0:r.label)??(i==null?void 0:i.testScenario)??null}function H({changes:e}){const{t:i}=R(),[c,r]=v.useState(null);return e.length===0?t.jsx("div",{className:s.feedEmpty,children:i("overview.feed.empty")}):t.jsx("div",{className:s.feedList,children:e.map((a,n)=>{const l=c===n,m=a.raw,g=m&&(m.before!=null||m.after!=null||m.details!=null),_=Oe(m);return t.jsxs("div",{children:[t.jsxs("div",{className:`${s.feedItem} ${g?s.feedItemClickable:""}`,onClick:()=>g&&r(l?null:n),children:[t.jsx("span",{className:s.feedTime,children:a.timestamp}),t.jsx("span",{className:s.feedIcon,children:a.icon}),t.jsxs("span",{className:s.feedText,children:[t.jsx("span",{className:s.feedSummary,children:a.summary}),_&&t.jsx("span",{className:s.feedContext,children:_})]}),g&&t.jsx("span",{className:s.feedChevron,children:l?"▴":"▾"})]}),l&&m&&t.jsx("div",{className:s.feedDetail,children:t.jsx(X,{change:m})})]},n)})})}const E=20;function G(e){return`${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`}function P(){return G(new Date)}function $(e){switch(e){case"script":return"📝";case"instance":return"🧱";case"property":return"🎨";case"lighting":return"💡";case"terrain":return"⛰️";case"asset":return"📦";default:return"🔧"}}function Xe(){const{level:e,status:i}=L(),c=F(),[r,a]=v.useState(null),[n,l]=v.useState(null),[m,g]=v.useState(null),[_,h]=v.useState([]),y=v.useRef(null),T=v.useCallback(async()=>{try{const o=await M.get("/connection-info");a(o)}catch{a(null)}},[]),S=v.useCallback(async()=>{try{const o=await M.get("/api/dashboard/changelog/active");if(g(o),o.recentChanges&&o.recentChanges.length>0){const p=o.recentChanges.map(x=>({timestamp:x.timestamp?G(new Date(x.timestamp)):P(),icon:$(x.category),summary:x.summary,category:x.category,raw:x}));h(p)}}catch{g(null)}},[]),f=v.useCallback(async()=>{try{const o=await M.get("/sync/status");l(o)}catch{l(null)}},[]);return v.useEffect(()=>{e!=="disconnected"?(T(),S(),f()):(a(null),l(null),g(null));const o=new V;y.current=o,o.connect();const p=o.on("game_change",C=>{const u=C,j={timestamp:P(),icon:$(u.category),summary:u.summary,category:u.category};h(k=>{const w=[j,...k];return w.length>E?w.slice(0,E):w}),S()}),x=o.on("sync",C=>{const u=C;l(j=>({...j,state:u.status,...u.placeId?{placeId:u.placeId}:{}}))});return()=>{p(),x(),o.disconnect(),y.current=null}},[e,T,S,f]),{level:e,status:i,connectionInfo:r,syncStatus:n,changeSummary:m,recentChanges:_,tier:c}}function D(e){return e.scriptsModified+e.scriptsCreated+e.instancesCreated+e.instancesDeleted+e.instancesMoved+e.propertiesChanged+e.assetsInserted+(e.lightingChanged?1:0)+(e.terrainChanged?1:0)}function qe(e,i){switch(e){case"syncing":return i("status.syncing","Syncing");case"initializing":return i("status.initializing","Initializing");case"error":return i("status.error","Error");default:return i("status.idle","Idle")}}function Je(e){switch(e){case"syncing":return"ok";case"initializing":return"warn";case"error":return"error";default:return"ok"}}function b(e,i,c,r){return t.jsxs("div",{className:e.metricSubtitle,children:[t.jsx(A,{label:i,tooltip:c}),": ",r]},i)}function d(e,i){return t.jsx(O,{text:i,children:e})}function nt(){var w,B;const{t:e}=R(),{level:i,status:c,connectionInfo:r,syncStatus:a,changeSummary:n,recentChanges:l}=Xe(),m=q(c==null?void 0:c.uptime),g=t.jsx(U,{title:e("page.overview.title","Overview"),description:e("page.overview.description","Check server, plugin, agent, sync, and recent game-change status in one place."),helpTopicId:"overview",helpState:{connectionLevel:i}});if(i==="disconnected")return t.jsxs("div",{className:s.page,children:[g,t.jsxs("div",{className:s.disconnectCard,children:[t.jsx("div",{className:s.disconnectIcon,children:"⚠️"}),t.jsx("h2",{className:s.disconnectTitle,children:e("overview.l0.title")}),t.jsx("p",{className:s.disconnectMessage,children:e("overview.l0.message")}),t.jsxs("div",{className:s.reconnectGuide,children:[t.jsxs("div",{className:s.guideStep,children:[t.jsx("span",{className:s.stepNumber,children:"1"}),t.jsx("span",{children:e("overview.l0.step1")})]}),t.jsxs("div",{className:s.guideStep,children:[t.jsx("span",{className:s.stepNumber,children:"2"}),t.jsx("span",{children:e("overview.l0.step2")})]})]}),t.jsxs("div",{className:s.reconnectIndicator,children:[t.jsx("span",{className:s.reconnectDot}),e("overview.l0.reconnecting")]}),t.jsxs("div",{className:s.disconnectActions,children:[t.jsx("button",{className:s.btn,onClick:()=>window.location.reload(),children:e("overview.l0.reconnectBtn")}),t.jsx("button",{className:s.btnSecondary,onClick:()=>{window.location.hash="#/settings"},children:e("overview.l0.settingsBtn")})]})]})]});const _=(r==null?void 0:r.mcpInstanceCount)??0,h=((w=r==null?void 0:r.mcpInstances)==null?void 0:w.find(I=>!I.isServer&&I.aiClientName))??((B=r==null?void 0:r.mcpInstances)==null?void 0:B.find(I=>!!I.aiClientName))??null,y=(c==null?void 0:c.pluginClients)??[],T=y.length>0,S=(c==null?void 0:c.sessionId)??(r==null?void 0:r.sessionId)??"-",f=e("overview.metric.server.tooltip","MCP server runtime and process status"),o=e("overview.metric.plugin.tooltip","Roblox Studio plugin connection and version status"),p=e("overview.metric.agent.tooltip","Connected AI coding agents and their runtime state"),x=e("overview.metric.sync.tooltip","Current Studio to local sync activity"),C=c?[b(s,e("overview.meta.version","Version"),e("overview.meta.version.tooltip","Installed MCP server version"),`v${c.version}`),b(s,e("overview.meta.session","Session"),e("overview.meta.session.tooltip","Current MCP session identifier"),S),b(s,e("overview.meta.pid","PID"),e("overview.meta.pid.tooltip","Operating system process identifier"),String(c.pid??"-")),b(s,e("overview.meta.uptime","Uptime"),e("overview.meta.uptime.tooltip","Time elapsed since the MCP server started"),J(m??c.uptime))]:[];if(i==="serverOnly")return t.jsxs("div",{className:s.page,children:[g,t.jsxs("div",{className:s.metricRow,children:[t.jsx(N,{title:d(e("overview.metric.server"),f),value:d(e("status.online"),f),icon:"🖥️",status:"ok",children:t.jsxs(t.Fragment,{children:[C,t.jsx(z,{status:"online"})]})}),t.jsx(N,{title:d(e("overview.metric.agent"),p),value:d((h==null?void 0:h.aiClientName)??e("overview.metric.noAgent"),p),icon:"🤖",subtitle:_>1?`${_} ${e("overview.metric.agent.instancesUnit","instances")}`:void 0,status:h?"ok":"warn"})]}),t.jsxs("div",{className:s.guideCard,children:[t.jsx("h3",{className:s.guideTitle,children:e("overview.l1.pluginGuide")}),t.jsxs("ul",{className:s.checklist,children:[t.jsx("li",{children:e("overview.l1.check1")}),t.jsx("li",{children:e("overview.l1.check2")})]})]}),t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.feed.title")}),l.length>0?t.jsx(H,{changes:l}):t.jsx("div",{className:s.feedEmpty,children:e("overview.l1.feedHint")})]}),n&&D(n)>0&&t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.changelog.title")}),t.jsxs("div",{className:s.changelogSummary,children:[t.jsxs("span",{children:[e("overview.changelog.entries","Entries"),": ",D(n)]}),n.scriptsModified>0&&t.jsxs("span",{className:s.changeTag,children:["📝"," ",n.scriptsModified," ",e("overview.changelog.scripts")]}),n.instancesCreated>0&&t.jsxs("span",{className:s.changeTag,children:["🧱"," ",n.instancesCreated," ",e("overview.changelog.instances")]}),n.propertiesChanged>0&&t.jsxs("span",{className:s.changeTag,children:["🎨"," ",n.propertiesChanged," ",e("overview.changelog.properties")]}),n.assetsInserted>0&&t.jsxs("span",{className:s.changeTag,children:["📦"," ",n.assetsInserted," ",e("overview.changelog.assets")]})]})]})]});const u=y[0],j=n?D(n):0,k=!!n&&j>0;return t.jsxs("div",{className:s.page,children:[g,t.jsxs("div",{className:s.metricGrid,children:[t.jsx(N,{title:d(e("overview.metric.server"),f),value:d(e("status.online"),f),icon:"🖥️",status:"ok",children:t.jsx(t.Fragment,{children:C})}),t.jsx(N,{title:d(e("overview.metric.plugin"),o),value:d(e(T?"status.online":"status.offline"),o),icon:"🔌",subtitle:u?`${u.placeName??"-"} / v${u.pluginVersion??"-"}`:void 0,status:T?"ok":"error"}),t.jsx(N,{title:d(e("overview.metric.agent"),p),value:d((h==null?void 0:h.aiClientName)??e("overview.metric.noAgent"),p),icon:"🤖",subtitle:_>1?`${_} ${e("overview.metric.agent.instancesUnit","instances")}`:void 0,status:h?"ok":"warn"}),t.jsx(N,{title:d(e("overview.metric.sync"),x),value:d(qe(a==null?void 0:a.state,e),x),icon:"🔄",status:Je(a==null?void 0:a.state)})]}),t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.feed.title")}),t.jsx(H,{changes:l})]}),k&&t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.changelog.title")}),t.jsxs("div",{className:s.changelogSummary,children:[t.jsxs("span",{children:[e("overview.changelog.entries","Entries"),": ",j]}),n.scriptsModified>0&&t.jsxs("span",{className:s.changeTag,children:["📝"," ",n.scriptsModified," ",e("overview.changelog.scripts")]}),n.instancesCreated>0&&t.jsxs("span",{className:s.changeTag,children:["🧱"," ",n.instancesCreated," ",e("overview.changelog.instances")]}),n.propertiesChanged>0&&t.jsxs("span",{className:s.changeTag,children:["🎨"," ",n.propertiesChanged," ",e("overview.changelog.properties")]}),n.assetsInserted>0&&t.jsxs("span",{className:s.changeTag,children:["📦"," ",n.assetsInserted," ",e("overview.changelog.assets")]})]})]})]})}export{nt as Component};
1
+ import{j as t,u as R,r as v,f as L,h as F,a as M,D as V}from"./index-C_exRd2o.js";import{I as A}from"./InfoLabel-HLPMIIL4.js";import{P as U}from"./PageHeader-Cvi0LO4r.js";import{S as z}from"./StatusBadge-Cf1Ncow3.js";import{T as O}from"./TooltipText-1fJvqtMt.js";import{G as X}from"./GameChangeDetail-Bd5Hg2ZD.js";import{u as q,f as J}from"./useLiveUptime-D0TQTjV7.js";import"./UiPrimitive-CsV5QE01.js";const K="_page_1xgxh_2",Q="_card_1xgxh_10",W="_cardHeader_1xgxh_17",Y="_disconnectCard_1xgxh_28",Z="_disconnectIcon_1xgxh_36",ee="_disconnectTitle_1xgxh_41",te="_disconnectMessage_1xgxh_48",se="_reconnectGuide_1xgxh_55",ne="_guideStep_1xgxh_64",ie="_stepNumber_1xgxh_72",ce="_reconnectIndicator_1xgxh_88",re="_reconnectDot_1xgxh_98",ae="_pulse_1xgxh_1",oe="_disconnectActions_1xgxh_112",le="_btn_1xgxh_118",de="_btnSecondary_1xgxh_134",me="_metricRow_1xgxh_152",ge="_metricGrid_1xgxh_158",he="_metricCard_1xgxh_164",xe="_metric_ok_1xgxh_174",ue="_metric_warn_1xgxh_179",ve="_metric_error_1xgxh_184",_e="_metricHeader_1xgxh_189",pe="_metricIcon_1xgxh_200",fe="_metricTitle_1xgxh_204",Ce="_metricValue_1xgxh_208",je="_metricSubtitle_1xgxh_215",we="_guideCard_1xgxh_225",Ne="_guideTitle_1xgxh_232",ye="_checklist_1xgxh_239",Te="_feedEmpty_1xgxh_263",Se="_feedList_1xgxh_270",Ie="_feedItem_1xgxh_278",be="_feedTime_1xgxh_291",ke="_feedIcon_1xgxh_298",Me="_feedSummary_1xgxh_304",De="_feedText_1xgxh_313",Be="_feedContext_1xgxh_321",He="_feedItemClickable_1xgxh_330",Ee="_feedChevron_1xgxh_338",Pe="_feedDetail_1xgxh_347",$e="_feedDetailPre_1xgxh_356",Re="_feedDetailText_1xgxh_365",Ge="_changelogSummary_1xgxh_372",Le="_changeTag_1xgxh_381",Fe="_tierBar_1xgxh_393",Ve="_tierBarTrack_1xgxh_399",Ae="_tierBarFillBasic_1xgxh_407",Ue="_tierBarFillPro_1xgxh_412",ze="_tierLabels_1xgxh_417",s={page:K,card:Q,cardHeader:W,disconnectCard:Y,disconnectIcon:Z,disconnectTitle:ee,disconnectMessage:te,reconnectGuide:se,guideStep:ne,stepNumber:ie,reconnectIndicator:ce,reconnectDot:re,pulse:ae,disconnectActions:oe,btn:le,btnSecondary:de,metricRow:me,metricGrid:ge,metricCard:he,metric_ok:xe,metric_warn:ue,metric_error:ve,metricHeader:_e,metricIcon:pe,metricTitle:fe,metricValue:Ce,metricSubtitle:je,guideCard:we,guideTitle:Ne,checklist:ye,feedEmpty:Te,feedList:Se,feedItem:Ie,feedTime:be,feedIcon:ke,feedSummary:Me,feedText:De,feedContext:Be,feedItemClickable:He,feedChevron:Ee,feedDetail:Pe,feedDetailPre:$e,feedDetailText:Re,changelogSummary:Ge,changeTag:Le,tierBar:Fe,tierBarTrack:Ve,tierBarFillBasic:Ae,tierBarFillPro:Ue,tierLabels:ze};function N({title:e,value:i,icon:c,subtitle:r,status:a,children:n}){const l=a?s[`metric_${a}`]:"";return t.jsxs("div",{className:`${s.metricCard} ${l}`,children:[t.jsxs("div",{className:s.metricHeader,children:[c&&t.jsx("span",{className:s.metricIcon,children:c}),t.jsx("span",{className:s.metricTitle,children:e})]}),t.jsx("div",{className:s.metricValue,children:i}),r&&t.jsx("div",{className:s.metricSubtitle,children:r}),n]})}function Oe(e){var c,r;const i=e==null?void 0:e.contextSummary;return(i==null?void 0:i.intent)??((r=(c=i==null?void 0:i.affectedAreas)==null?void 0:c[0])==null?void 0:r.label)??(i==null?void 0:i.testScenario)??null}function H({changes:e}){const{t:i}=R(),[c,r]=v.useState(null);return e.length===0?t.jsx("div",{className:s.feedEmpty,children:i("overview.feed.empty")}):t.jsx("div",{className:s.feedList,children:e.map((a,n)=>{const l=c===n,m=a.raw,g=m&&(m.before!=null||m.after!=null||m.details!=null),_=Oe(m);return t.jsxs("div",{children:[t.jsxs("div",{className:`${s.feedItem} ${g?s.feedItemClickable:""}`,onClick:()=>g&&r(l?null:n),children:[t.jsx("span",{className:s.feedTime,children:a.timestamp}),t.jsx("span",{className:s.feedIcon,children:a.icon}),t.jsxs("span",{className:s.feedText,children:[t.jsx("span",{className:s.feedSummary,children:a.summary}),_&&t.jsx("span",{className:s.feedContext,children:_})]}),g&&t.jsx("span",{className:s.feedChevron,children:l?"▴":"▾"})]}),l&&m&&t.jsx("div",{className:s.feedDetail,children:t.jsx(X,{change:m})})]},n)})})}const E=20;function G(e){return`${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`}function P(){return G(new Date)}function $(e){switch(e){case"script":return"📝";case"instance":return"🧱";case"property":return"🎨";case"lighting":return"💡";case"terrain":return"⛰️";case"asset":return"📦";default:return"🔧"}}function Xe(){const{level:e,status:i}=L(),c=F(),[r,a]=v.useState(null),[n,l]=v.useState(null),[m,g]=v.useState(null),[_,h]=v.useState([]),y=v.useRef(null),T=v.useCallback(async()=>{try{const o=await M.get("/connection-info");a(o)}catch{a(null)}},[]),S=v.useCallback(async()=>{try{const o=await M.get("/api/dashboard/changelog/active");if(g(o),o.recentChanges&&o.recentChanges.length>0){const p=o.recentChanges.map(x=>({timestamp:x.timestamp?G(new Date(x.timestamp)):P(),icon:$(x.category),summary:x.summary,category:x.category,raw:x}));h(p)}}catch{g(null)}},[]),f=v.useCallback(async()=>{try{const o=await M.get("/sync/status");l(o)}catch{l(null)}},[]);return v.useEffect(()=>{e!=="disconnected"?(T(),S(),f()):(a(null),l(null),g(null));const o=new V;y.current=o,o.connect();const p=o.on("game_change",C=>{const u=C,j={timestamp:P(),icon:$(u.category),summary:u.summary,category:u.category};h(k=>{const w=[j,...k];return w.length>E?w.slice(0,E):w}),S()}),x=o.on("sync",C=>{const u=C;l(j=>({...j,state:u.status,...u.placeId?{placeId:u.placeId}:{}}))});return()=>{p(),x(),o.disconnect(),y.current=null}},[e,T,S,f]),{level:e,status:i,connectionInfo:r,syncStatus:n,changeSummary:m,recentChanges:_,tier:c}}function D(e){return e.scriptsModified+e.scriptsCreated+e.instancesCreated+e.instancesDeleted+e.instancesMoved+e.propertiesChanged+e.assetsInserted+(e.lightingChanged?1:0)+(e.terrainChanged?1:0)}function qe(e,i){switch(e){case"syncing":return i("status.syncing","Syncing");case"initializing":return i("status.initializing","Initializing");case"error":return i("status.error","Error");default:return i("status.idle","Idle")}}function Je(e){switch(e){case"syncing":return"ok";case"initializing":return"warn";case"error":return"error";default:return"ok"}}function b(e,i,c,r){return t.jsxs("div",{className:e.metricSubtitle,children:[t.jsx(A,{label:i,tooltip:c}),": ",r]},i)}function d(e,i){return t.jsx(O,{text:i,children:e})}function nt(){var w,B;const{t:e}=R(),{level:i,status:c,connectionInfo:r,syncStatus:a,changeSummary:n,recentChanges:l}=Xe(),m=q(c==null?void 0:c.uptime),g=t.jsx(U,{title:e("page.overview.title","Overview"),description:e("page.overview.description","Check server, plugin, agent, sync, and recent game-change status in one place."),helpTopicId:"overview",helpState:{connectionLevel:i}});if(i==="disconnected")return t.jsxs("div",{className:s.page,children:[g,t.jsxs("div",{className:s.disconnectCard,children:[t.jsx("div",{className:s.disconnectIcon,children:"⚠️"}),t.jsx("h2",{className:s.disconnectTitle,children:e("overview.l0.title")}),t.jsx("p",{className:s.disconnectMessage,children:e("overview.l0.message")}),t.jsxs("div",{className:s.reconnectGuide,children:[t.jsxs("div",{className:s.guideStep,children:[t.jsx("span",{className:s.stepNumber,children:"1"}),t.jsx("span",{children:e("overview.l0.step1")})]}),t.jsxs("div",{className:s.guideStep,children:[t.jsx("span",{className:s.stepNumber,children:"2"}),t.jsx("span",{children:e("overview.l0.step2")})]})]}),t.jsxs("div",{className:s.reconnectIndicator,children:[t.jsx("span",{className:s.reconnectDot}),e("overview.l0.reconnecting")]}),t.jsxs("div",{className:s.disconnectActions,children:[t.jsx("button",{className:s.btn,onClick:()=>window.location.reload(),children:e("overview.l0.reconnectBtn")}),t.jsx("button",{className:s.btnSecondary,onClick:()=>{window.location.hash="#/settings"},children:e("overview.l0.settingsBtn")})]})]})]});const _=(r==null?void 0:r.mcpInstanceCount)??0,h=((w=r==null?void 0:r.mcpInstances)==null?void 0:w.find(I=>!I.isServer&&I.aiClientName))??((B=r==null?void 0:r.mcpInstances)==null?void 0:B.find(I=>!!I.aiClientName))??null,y=(c==null?void 0:c.pluginClients)??[],T=y.length>0,S=(c==null?void 0:c.sessionId)??(r==null?void 0:r.sessionId)??"-",f=e("overview.metric.server.tooltip","MCP server runtime and process status"),o=e("overview.metric.plugin.tooltip","Roblox Studio plugin connection and version status"),p=e("overview.metric.agent.tooltip","Connected AI coding agents and their runtime state"),x=e("overview.metric.sync.tooltip","Current Studio to local sync activity"),C=c?[b(s,e("overview.meta.version","Version"),e("overview.meta.version.tooltip","Installed MCP server version"),`v${c.version}`),b(s,e("overview.meta.session","Session"),e("overview.meta.session.tooltip","Current MCP session identifier"),S),b(s,e("overview.meta.pid","PID"),e("overview.meta.pid.tooltip","Operating system process identifier"),String(c.pid??"-")),b(s,e("overview.meta.uptime","Uptime"),e("overview.meta.uptime.tooltip","Time elapsed since the MCP server started"),J(m??c.uptime))]:[];if(i==="serverOnly")return t.jsxs("div",{className:s.page,children:[g,t.jsxs("div",{className:s.metricRow,children:[t.jsx(N,{title:d(e("overview.metric.server"),f),value:d(e("status.online"),f),icon:"🖥️",status:"ok",children:t.jsxs(t.Fragment,{children:[C,t.jsx(z,{status:"online"})]})}),t.jsx(N,{title:d(e("overview.metric.agent"),p),value:d((h==null?void 0:h.aiClientName)??e("overview.metric.noAgent"),p),icon:"🤖",subtitle:_>1?`${_} ${e("overview.metric.agent.instancesUnit","instances")}`:void 0,status:h?"ok":"warn"})]}),t.jsxs("div",{className:s.guideCard,children:[t.jsx("h3",{className:s.guideTitle,children:e("overview.l1.pluginGuide")}),t.jsxs("ul",{className:s.checklist,children:[t.jsx("li",{children:e("overview.l1.check1")}),t.jsx("li",{children:e("overview.l1.check2")})]})]}),t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.feed.title")}),l.length>0?t.jsx(H,{changes:l}):t.jsx("div",{className:s.feedEmpty,children:e("overview.l1.feedHint")})]}),n&&D(n)>0&&t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.changelog.title")}),t.jsxs("div",{className:s.changelogSummary,children:[t.jsxs("span",{children:[e("overview.changelog.entries","Entries"),": ",D(n)]}),n.scriptsModified>0&&t.jsxs("span",{className:s.changeTag,children:["📝"," ",n.scriptsModified," ",e("overview.changelog.scripts")]}),n.instancesCreated>0&&t.jsxs("span",{className:s.changeTag,children:["🧱"," ",n.instancesCreated," ",e("overview.changelog.instances")]}),n.propertiesChanged>0&&t.jsxs("span",{className:s.changeTag,children:["🎨"," ",n.propertiesChanged," ",e("overview.changelog.properties")]}),n.assetsInserted>0&&t.jsxs("span",{className:s.changeTag,children:["📦"," ",n.assetsInserted," ",e("overview.changelog.assets")]})]})]})]});const u=y[0],j=n?D(n):0,k=!!n&&j>0;return t.jsxs("div",{className:s.page,children:[g,t.jsxs("div",{className:s.metricGrid,children:[t.jsx(N,{title:d(e("overview.metric.server"),f),value:d(e("status.online"),f),icon:"🖥️",status:"ok",children:t.jsx(t.Fragment,{children:C})}),t.jsx(N,{title:d(e("overview.metric.plugin"),o),value:d(e(T?"status.online":"status.offline"),o),icon:"🔌",subtitle:u?`${u.placeName??"-"} / v${u.pluginVersion??"-"}`:void 0,status:T?"ok":"error"}),t.jsx(N,{title:d(e("overview.metric.agent"),p),value:d((h==null?void 0:h.aiClientName)??e("overview.metric.noAgent"),p),icon:"🤖",subtitle:_>1?`${_} ${e("overview.metric.agent.instancesUnit","instances")}`:void 0,status:h?"ok":"warn"}),t.jsx(N,{title:d(e("overview.metric.sync"),x),value:d(qe(a==null?void 0:a.state,e),x),icon:"🔄",status:Je(a==null?void 0:a.state)})]}),t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.feed.title")}),t.jsx(H,{changes:l})]}),k&&t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.changelog.title")}),t.jsxs("div",{className:s.changelogSummary,children:[t.jsxs("span",{children:[e("overview.changelog.entries","Entries"),": ",j]}),n.scriptsModified>0&&t.jsxs("span",{className:s.changeTag,children:["📝"," ",n.scriptsModified," ",e("overview.changelog.scripts")]}),n.instancesCreated>0&&t.jsxs("span",{className:s.changeTag,children:["🧱"," ",n.instancesCreated," ",e("overview.changelog.instances")]}),n.propertiesChanged>0&&t.jsxs("span",{className:s.changeTag,children:["🎨"," ",n.propertiesChanged," ",e("overview.changelog.properties")]}),n.assetsInserted>0&&t.jsxs("span",{className:s.changeTag,children:["📦"," ",n.assetsInserted," ",e("overview.changelog.assets")]})]})]})]})}export{nt as Component};
@@ -1,4 +1,4 @@
1
- import{i as te,u as oe,e as ne,r as p,j as t,X as se,E as ae,k as re,K as ie}from"./index-B1MZBjK4.js";import{I as X,a as le}from"./UiPrimitive-ojecpNs1.js";/**
1
+ import{i as te,u as oe,e as ne,r as p,j as t,X as se,E as ae,k as re,K as ie}from"./index-C_exRd2o.js";import{I as X,a as le}from"./UiPrimitive-CsV5QE01.js";/**
2
2
  * @license lucide-react v1.8.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{r as l,a as v,u as N,j as t,e as D,h as E,l as $,T as U}from"./index-B1MZBjK4.js";import{P as O}from"./PageHeader-DezmLDg1.js";import{I as B}from"./InfoLabel-Cc4MKAYc.js";import{C as F}from"./CurrentPlaceScope-DJheb09C.js";import{T as S}from"./TooltipText-CMx5IM6p.js";import{C as V}from"./ConfirmModal-BXbkJq3w.js";import"./UiPrimitive-ojecpNs1.js";import"./ConfirmModal.module-DJksQHBd.js";const W=5e3;function T(e){if(typeof e=="number")return{placeId:String(e)}}function z(e,o){return typeof o!="number"?e:`${e}?placeId=${encodeURIComponent(String(o))}`}function G(e){const o=(e==null?void 0:e.enabled)??!0,r=(e==null?void 0:e.placeId)??null,[n,a]=l.useState([]),[m,i]=l.useState(null),[p,c]=l.useState(o),d=l.useRef(null),u=l.useCallback(async()=>{try{const y=T(r),x=y?await v.get("/api/dashboard/playtest/history",y):await v.get("/api/dashboard/playtest/history");a(x.entries??[])}catch{}},[r]),h=l.useCallback(async()=>{if(!o){c(!1);return}await u(),c(!1)},[o,u]),g=l.useCallback(async()=>{o&&(await v.post(z("/api/dashboard/playtest/history/clear",r)),a([]),i(null))},[o,r]);l.useEffect(()=>{i(null)},[r]);const f=l.useCallback(async y=>{if(o)try{const x=T(r),w=x?await v.get(`/api/dashboard/playtest/report/${y}`,x):await v.get(`/api/dashboard/playtest/report/${y}`);i(w)}catch{i(null)}},[o,r]);return l.useEffect(()=>{if(!o){c(!1);return}return h(),d.current=setInterval(h,W),()=>{d.current&&clearInterval(d.current)}},[o,h]),{history:n,selectedReport:m,loading:p,loadReport:f,clearHistory:g}}function Q(e){const o="2026-03-27T15:26:00.000Z",r={testScenario:e("playtest.sample.context.why","Spawn into the arena, survive the opener, and verify the HUD responds immediately."),expectedBehavior:e("playtest.sample.context.expected","The player spawns safely, the countdown UI appears within one second, and the first wave starts without errors."),observedBehavior:e("playtest.sample.context.observed","Spawn protection held, the HUD updated on time, and wave one completed with no gameplay regressions.")};return{history:[{timestamp:o,testName:e("playtest.sample.history.name","Sample Arena Smoke Test"),mode:"play",status:"passed",durationMs:4820,contextId:"sample_playtest_preview",contextSummary:r}],report:{markdown:e("playtest.sample.report.markdown",`# Sample Arena Smoke Test
1
+ import{r as l,a as v,u as N,j as t,e as D,h as E,l as $,T as U}from"./index-C_exRd2o.js";import{P as O}from"./PageHeader-Cvi0LO4r.js";import{I as B}from"./InfoLabel-HLPMIIL4.js";import{C as F}from"./CurrentPlaceScope-DrtUw6py.js";import{T as S}from"./TooltipText-1fJvqtMt.js";import{C as V}from"./ConfirmModal-DJp4ax33.js";import"./UiPrimitive-CsV5QE01.js";import"./ConfirmModal.module-DJksQHBd.js";const W=5e3;function T(e){if(typeof e=="number")return{placeId:String(e)}}function z(e,o){return typeof o!="number"?e:`${e}?placeId=${encodeURIComponent(String(o))}`}function G(e){const o=(e==null?void 0:e.enabled)??!0,r=(e==null?void 0:e.placeId)??null,[n,a]=l.useState([]),[m,i]=l.useState(null),[p,c]=l.useState(o),d=l.useRef(null),u=l.useCallback(async()=>{try{const y=T(r),x=y?await v.get("/api/dashboard/playtest/history",y):await v.get("/api/dashboard/playtest/history");a(x.entries??[])}catch{}},[r]),h=l.useCallback(async()=>{if(!o){c(!1);return}await u(),c(!1)},[o,u]),g=l.useCallback(async()=>{o&&(await v.post(z("/api/dashboard/playtest/history/clear",r)),a([]),i(null))},[o,r]);l.useEffect(()=>{i(null)},[r]);const f=l.useCallback(async y=>{if(o)try{const x=T(r),w=x?await v.get(`/api/dashboard/playtest/report/${y}`,x):await v.get(`/api/dashboard/playtest/report/${y}`);i(w)}catch{i(null)}},[o,r]);return l.useEffect(()=>{if(!o){c(!1);return}return h(),d.current=setInterval(h,W),()=>{d.current&&clearInterval(d.current)}},[o,h]),{history:n,selectedReport:m,loading:p,loadReport:f,clearHistory:g}}function Q(e){const o="2026-03-27T15:26:00.000Z",r={testScenario:e("playtest.sample.context.why","Spawn into the arena, survive the opener, and verify the HUD responds immediately."),expectedBehavior:e("playtest.sample.context.expected","The player spawns safely, the countdown UI appears within one second, and the first wave starts without errors."),observedBehavior:e("playtest.sample.context.observed","Spawn protection held, the HUD updated on time, and wave one completed with no gameplay regressions.")};return{history:[{timestamp:o,testName:e("playtest.sample.history.name","Sample Arena Smoke Test"),mode:"play",status:"passed",durationMs:4820,contextId:"sample_playtest_preview",contextSummary:r}],report:{markdown:e("playtest.sample.report.markdown",`# Sample Arena Smoke Test
2
2
 
3
3
  - Spawn flow: PASS
4
4
  - HUD countdown: PASS