@weppy/roblox-mcp 2.7.6 → 2.7.8

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 (29) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +8 -8
  3. package/dashboard/dist/assets/{ChangelogDetailPage-DglsIYkW.js → ChangelogDetailPage-B7ugySeq.js} +1 -1
  4. package/dashboard/dist/assets/{ChangelogPage-65B3_w0_.js → ChangelogPage-B7-iV5Ir.js} +1 -1
  5. package/dashboard/dist/assets/{ConfirmModal-Cpk7SbKb.js → ConfirmModal-Dg8_uxRE.js} +1 -1
  6. package/dashboard/dist/assets/{ConnectionPage-B-IN5LsC.js → ConnectionPage-COgl_4EK.js} +1 -1
  7. package/dashboard/dist/assets/{GameChangeDetail-DM3mWsFX.js → GameChangeDetail-D31gfmkK.js} +1 -1
  8. package/dashboard/dist/assets/{InfoLabel-B_fEbHa7.js → InfoLabel-Bp3j_i44.js} +1 -1
  9. package/dashboard/dist/assets/{OverviewPage-B4O0bv4R.js → OverviewPage-Bl67HNuU.js} +1 -1
  10. package/dashboard/dist/assets/{PlaytestPage-BHLRKn8U.js → PlaytestPage-D-gmWEk9.js} +1 -1
  11. package/dashboard/dist/assets/{SettingsPage-DmIKC_O1.js → SettingsPage-BdUpzUq9.js} +1 -1
  12. package/dashboard/dist/assets/{StatusBadge-DRdnq30k.js → StatusBadge-4qs9buFz.js} +1 -1
  13. package/dashboard/dist/assets/{SyncPage-CW_0kNpZ.js → SyncPage-BaOvmPdn.js} +1 -1
  14. package/dashboard/dist/assets/{Tabs-BsTVkBUh.js → Tabs-BCiSXsKz.js} +1 -1
  15. package/dashboard/dist/assets/{TierComparison-poRtDe46.js → TierComparison-Lkag7n54.js} +1 -1
  16. package/dashboard/dist/assets/{ToolsPage-D77yJ9jZ.js → ToolsPage-BHGtm0IX.js} +1 -1
  17. package/dashboard/dist/assets/{TooltipText-DX5jnyNF.js → TooltipText-Bgk-NYKr.js} +1 -1
  18. package/dashboard/dist/assets/{UiStudioPage-YtdlkQzT.js → UiStudioPage-CvpsOKcP.js} +1 -1
  19. package/dashboard/dist/assets/WhatsNewPage-D5OncQnl.css +1 -0
  20. package/dashboard/dist/assets/WhatsNewPage-g_24s3hx.js +1 -0
  21. package/dashboard/dist/assets/{index-BPIBy2lU.js → index-C9gmLH8z.js} +102 -44
  22. package/dashboard/dist/assets/{sample-requests-CwDMfktX.js → sample-requests-BSEgt_Th.js} +1 -1
  23. package/dashboard/dist/assets/{useLiveUptime-ElD9lDzh.js → useLiveUptime-gW3LP94r.js} +1 -1
  24. package/dashboard/dist/index.html +1 -1
  25. package/dist/index.js +1 -1
  26. package/package.json +1 -1
  27. package/roblox-plugin/WeppyRobloxMCP.rbxm +0 -0
  28. package/dashboard/dist/assets/WhatsNewPage--uCu0xCm.js +0 -1
  29. package/dashboard/dist/assets/WhatsNewPage-Lxgj0StO.css +0 -1
package/CHANGELOG.md CHANGED
@@ -8,6 +8,29 @@ All notable changes to this project will be documented in this file.
8
8
 
9
9
 
10
10
 
11
+
12
+
13
+ ## [2.7.8] - 2026-05-16
14
+
15
+ ### Features
16
+
17
+ - **French language support** — The WEPPY dashboard and Roblox Studio plugin now support French. Select **Français** from Settings to use the dashboard and plugin UI in French, and French systems are detected automatically when the language setting is set to Auto.
18
+
19
+ ### Stability
20
+
21
+ - **More reliable localized setup guidance** — The dashboard What's New page now supports multiple localized setup links in a single announcement, so Claude Code, Codex CLI, and Codex App users can jump directly to the correct install guide for their language.
22
+ - **Language selector consistency** — The plugin Settings language dropdown now uses the same supported locale list as the localization runtime, so every shipped language appears as an option.
23
+
24
+ ## [2.7.7] - 2026-05-14
25
+
26
+ ### Bug Fixes
27
+
28
+ - **Codex Plugin Directory installation** — The Codex marketplace entry now uses the installable plugin metadata expected by Codex and appears as **WEPPY Roblox AI Toolkit**. The MCP server id and npm command stay unchanged, while Codex users can install the plugin and load the included WEPPY skills from Plugin Directory.
29
+
30
+ ### Documentation
31
+
32
+ - **Clearer Claude Code and Codex setup names** — Install guides now use the same plugin id and display name across the public README, one-line installer guidance, and website docs, reducing confusion between the MCP server and the agent plugin.
33
+
11
34
  ## [2.7.6] - 2026-05-14
12
35
 
13
36
  ### Features
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  **English** | [한국어](https://weppyai.com/ko) | [日本語](https://weppyai.com/ja) | [Español](https://weppyai.com/es) | [Português](https://weppyai.com/pt-br) | [Bahasa Indonesia](https://weppyai.com/id) | [Deutsch](https://weppyai.com/de)
8
8
 
9
- [![Demo - AI building a Roblox game in real time](https://img.youtube.com/vi/puQB4u1VlMw/maxresdefault.jpg)](https://youtu.be/puQB4u1VlMw)
9
+ [![Demo - AI building a Roblox game in real time](https://img.youtube.com/vi/j14LZHYzLg8/maxresdefault.jpg)](https://www.youtube.com/watch?v=j14LZHYzLg8)
10
10
 
11
11
  ## Why WEPPY (Weppy Roblox MCP)?
12
12
 
@@ -41,7 +41,7 @@ irm https://raw.githubusercontent.com/hope1026/weppy-roblox-mcp/main/install.ps1
41
41
  Then reopen your AI app and restart Roblox Studio.
42
42
 
43
43
  Automatic MCP registration supports Claude Code, Claude Desktop, Cursor, Codex CLI/App, Gemini CLI, and Antigravity.
44
- For Claude Code, the installer also tries to add and install the WEPPY AI Agent Plugin. For Codex, it adds the WEPPY AI Agent Plugin marketplace and then asks you to install WEPPY Roblox MCP from Plugin Directory.
44
+ For Claude Code, the installer also tries to add and install the WEPPY Roblox AI Toolkit. For Codex, it adds the WEPPY Roblox AI Toolkit marketplace and then asks you to install WEPPY Roblox AI Toolkit from Plugin Directory.
45
45
 
46
46
  ### Manual Install
47
47
 
@@ -61,15 +61,15 @@ Supported AI apps are Claude Code, Claude Desktop, Cursor, Codex CLI, Codex App,
61
61
 
62
62
  > Any MCP-compatible AI client works. The server command is `npx -y @weppy/roblox-mcp@latest`.
63
63
 
64
- ### Optional WEPPY AI Agent Plugin
64
+ ### Optional WEPPY Roblox AI Toolkit
65
65
 
66
- Claude Code and Codex can also use the WEPPY AI Agent Plugin. The MCP server command above is enough to use WEPPY; the plugin adds client-native setup and workflow guidance.
66
+ Claude Code and Codex can also use the WEPPY Roblox AI Toolkit. The MCP server command above is enough to use WEPPY; the plugin adds client-native setup and workflow guidance.
67
67
 
68
68
  **Claude Code**
69
69
 
70
70
  ```bash
71
71
  claude plugin marketplace add hope1026/weppy-roblox-mcp --scope user
72
- claude plugin install weppy-roblox-mcp@hope1026-roblox-mcp --scope user
72
+ claude plugin install weppy-roblox-ai-toolkit@hope1026-roblox-mcp --scope user
73
73
  ```
74
74
 
75
75
  **Codex**
@@ -78,7 +78,7 @@ claude plugin install weppy-roblox-mcp@hope1026-roblox-mcp --scope user
78
78
  codex plugin marketplace add hope1026/weppy-roblox-mcp
79
79
  ```
80
80
 
81
- After adding the Codex marketplace, restart Codex, open Plugin Directory, and install **WEPPY Roblox MCP**.
81
+ After adding the Codex marketplace, restart Codex, open Plugin Directory, and install **WEPPY Roblox AI Toolkit**.
82
82
 
83
83
  ## Compatibility
84
84
 
@@ -180,10 +180,10 @@ For app setup details, open the web docs hub and choose the relevant AI client g
180
180
  ## FAQ
181
181
 
182
182
  ### How do I connect Claude Code to Roblox Studio?
183
- Install from the web install page or add the WEPPY AI Agent Plugin for Claude Code with the commands above. The WEPPY AI Agent Plugin uses `npx -y @weppy/roblox-mcp@latest` as the MCP server command.
183
+ Install from the web install page or add the WEPPY Roblox AI Toolkit for Claude Code with the commands above. The WEPPY Roblox AI Toolkit uses `npx -y @weppy/roblox-mcp@latest` as the MCP server command.
184
184
 
185
185
  ### How do I use Codex CLI with Roblox Studio?
186
- Install the Roblox Studio plugin, then add the MCP server config to Codex CLI. You can also add the Codex plugin marketplace and install WEPPY Roblox MCP from Plugin Directory.
186
+ Install the Roblox Studio plugin, then add the MCP server config to Codex CLI. You can also add the Codex plugin marketplace and install WEPPY Roblox AI Toolkit from Plugin Directory.
187
187
 
188
188
  ### Does Roblox MCP work with Cursor?
189
189
  Yes. Any MCP-compatible AI client works.
@@ -1 +1 @@
1
- import{r,a as R,u as M,b as B,c as V,j as e}from"./index-BPIBy2lU.js";import{I as G}from"./InfoLabel-B_fEbHa7.js";import{G as D}from"./GameChangeDetail-DM3mWsFX.js";import{T as m}from"./TooltipText-DX5jnyNF.js";function F(n){const s={scriptsModified:0,scriptsCreated:0,instancesCreated:0,instancesDeleted:0,instancesMoved:0,propertiesChanged:0,lightingChanged:!1,terrainChanged:!1,assetsInserted:0};for(const l of n)switch(l.category){case"script":l.changeType==="create"?s.scriptsCreated++:s.scriptsModified++;break;case"instance":l.changeType==="create"?s.instancesCreated++:l.changeType==="delete"?s.instancesDeleted++:l.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 P(n){const[s,l]=r.useState(""),[a,d]=r.useState(""),[u,q]=r.useState(),[w,y]=r.useState("completed"),[I,E]=r.useState([]),[L,O]=r.useState([]),[x,f]=r.useState([]),[p,_]=r.useState(),[j,b]=r.useState(),[v,S]=r.useState(),[C,N]=r.useState({scriptsModified:0,scriptsCreated:0,instancesCreated:0,instancesDeleted:0,instancesMoved:0,propertiesChanged:0,lightingChanged:!1,terrainChanged:!1,assetsInserted:0}),[T,g]=r.useState(!0),[k,h]=r.useState(null),i=r.useCallback(async()=>{if(n){g(!0),h(null);try{const[c,o]=await Promise.all([R.get(`/api/dashboard/changelog/${n}`),R.get(`/api/dashboard/changelog/${n}/changes`)]);l(c.entryId),d(c.startTime),q(c.endTime),y(c.status),E(c.entries),O(c.failures),_(c.contextSummary),b(c.replayMetadata),S(c.verificationSummary),f(o.changes),N(F(o.changes))}catch(c){h(c instanceof Error?c.message:"Failed to load changelog detail")}finally{g(!1)}}},[n]);return r.useEffect(()=>{i()},[i]),{entryId:s,startTime:a,endTime:u,status:w,entries:I,failures:L,changes:x,changeSummary:C,contextSummary:p,replayMetadata:j,verificationSummary:v,loading:T,error:k,refresh:i}}const U={script:"📝",instance:"🧱",property:"🎨",lighting:"🌅",terrain:"⛰️",asset:"📦"};function H(n){return U[n]??"❓"}const W="_page_q2jbi_2",Y="_header_q2jbi_10",z="_backLink_q2jbi_16",J="_headerTitle_q2jbi_29",Q="_headerTime_q2jbi_37",X="_statusActive_q2jbi_44",Z="_statusCompleted_q2jbi_49",ee="_section_q2jbi_54",te="_sectionTitle_q2jbi_61",ne="_summaryGrid_q2jbi_74",ae="_summaryCard_q2jbi_80",ie="_summaryCardActive_q2jbi_94",se="_summaryIcon_q2jbi_99",ce="_summaryCount_q2jbi_105",re="_summaryLabel_q2jbi_112",oe="_contextGrid_q2jbi_121",le="_contextRow_q2jbi_127",de="_contextKey_q2jbi_133",me="_contextValue_q2jbi_141",ge="_timelineFilter_q2jbi_149",he="_filterLabel_q2jbi_156",ue="_filterSelect_q2jbi_162",ye="_timeline_q2jbi_149",xe="_timelineEntry_q2jbi_182",fe="_timelineTime_q2jbi_199",pe="_timelineIcon_q2jbi_207",_e="_timelineBody_q2jbi_212",je="_timelineSummary_q2jbi_217",be="_timelineTarget_q2jbi_224",ve="_timelineConfidence_q2jbi_231",Se="_confidenceExact_q2jbi_240",Ce="_confidencePartial_q2jbi_245",Ne="_confidenceAfterOnly_q2jbi_250",Te="_confidenceIntentOnly_q2jbi_255",ke="_confidenceUnknown_q2jbi_260",qe="_timelineExpanded_q2jbi_266",we="_empty_q2jbi_338",Ie="_loading_q2jbi_347",Ee="_error_q2jbi_356",t={page:W,header:Y,backLink:z,headerTitle:J,headerTime:Q,statusActive:X,statusCompleted:Z,section:ee,sectionTitle:te,summaryGrid:ne,summaryCard:ae,summaryCardActive:ie,summaryIcon:se,summaryCount:ce,summaryLabel:re,contextGrid:oe,contextRow:le,contextKey:de,contextValue:me,timelineFilter:ge,filterLabel:he,filterSelect:ue,timeline:ye,timelineEntry:xe,timelineTime:fe,timelineIcon:pe,timelineBody:_e,timelineSummary:je,timelineTarget:be,timelineConfidence:ve,confidenceExact:Se,confidencePartial:Ce,confidenceAfterOnly:Ne,confidenceIntentOnly:Te,confidenceUnknown:ke,timelineExpanded:qe,empty:we,loading:Ie,error:Ee},$=[{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 A(n){if(!n)return"--:--";const s=new Date(n);return`${String(s.getHours()).padStart(2,"0")}:${String(s.getMinutes()).padStart(2,"0")}`}function Le(n){if(!n)return"--:--:--";const s=new Date(n);return`${String(s.getHours()).padStart(2,"0")}:${String(s.getMinutes()).padStart(2,"0")}:${String(s.getSeconds()).padStart(2,"0")}`}function Oe(n,s){if(!n||!s)return"";const l=new Date(s).getTime()-new Date(n).getTime();return l<0?"":`${Math.round(l/6e4)}min`}function Ae(n){switch(n){case"exact":return t.confidenceExact;case"partial":return t.confidencePartial;case"after-only":return t.confidenceAfterOnly;case"intent-only":return t.confidenceIntentOnly;default:return t.confidenceUnknown}}function Ke(n,s){switch(s){case"exact":return n("changelog.detail.confidence.exact","Exact");case"partial":return n("changelog.detail.confidence.partial","Partial");case"after-only":return n("changelog.detail.confidence.afterOnly","After only");case"intent-only":return n("changelog.detail.confidence.intentOnly","Intent only");default:return n("changelog.detail.confidence.unknown","Unknown")}}function Re(n,s){switch(s){case"exact":return n("changelog.detail.confidence.exact.tooltip","Both the before and after state were confirmed for this change.");case"partial":return n("changelog.detail.confidence.partial.tooltip","Only part of the before and after state could be confirmed for this change.");case"after-only":return n("changelog.detail.confidence.afterOnly.tooltip","Only the resulting state after the change could be confirmed.");case"intent-only":return n("changelog.detail.confidence.intentOnly.tooltip","Only the requested action was recorded, not the resulting state.");default:return n("changelog.detail.confidence.unknown.tooltip","This change could not be confidently classified from the available data.")}}function Ge(){var x,f,p,_,j,b,v,S,C,N,T,g,k,h;const{t:n}=M(),{id:s}=B(),l=V(),a=P(s),[d,u]=r.useState("all"),[q,w]=r.useState(null),y=r.useMemo(()=>[...d==="all"?a.changes:a.changes.filter(c=>c.category===d)].reverse(),[a.changes,d]);if(a.loading)return e.jsx("div",{className:t.loading,children:n("common.loading","Loading...")});if(a.error)return e.jsxs("div",{className:t.error,children:[a.error,e.jsx("br",{}),e.jsxs("span",{className:t.backLink,onClick:()=>l("/changelog"),children:["←"," ",n("changelog.detail.backToList","Back to list")]})]});const I=Oe(a.startTime,a.endTime),E=a.endTime?`${A(a.startTime)} → ${A(a.endTime)} (${I})`:`${A(a.startTime)} → ${n("changelog.card.inProgress","in progress")}`,L=!!((x=a.contextSummary)!=null&&x.intent||(f=a.contextSummary)!=null&&f.testScenario||(p=a.contextSummary)!=null&&p.expectedBehavior||(_=a.contextSummary)!=null&&_.observedBehavior),O=!!((j=a.verificationSummary)!=null&&j.label||(b=a.verificationSummary)!=null&&b.status||(v=a.verificationSummary)!=null&&v.testTimestamp);return e.jsxs("div",{className:t.page,children:[e.jsxs("div",{className:t.header,children:[e.jsxs("span",{className:t.backLink,onClick:()=>l("/changelog"),children:["←"," ",n("sidebar.changelog","Changelog")]}),e.jsx("span",{className:t.headerTitle,children:"|"}),e.jsx("span",{className:t.headerTime,children:E}),e.jsx(m,{text:a.status==="active"?n("changelog.card.active.tooltip","This session is still receiving new game changes."):n("changelog.card.completed.tooltip","This session has ended and no more changes are expected."),children:e.jsx("span",{className:a.status==="active"?t.statusActive:t.statusCompleted,children:a.status==="active"?n("changelog.card.active","Active"):n("changelog.card.completed","Completed")})})]}),e.jsxs("div",{className:t.section,children:[e.jsx("div",{className:t.sectionTitle,children:e.jsx(m,{text:n("changelog.detail.changeSummary.tooltip","Counts of extracted game changes grouped by category for this session."),children:e.jsx("span",{children:n("changelog.detail.changeSummary","Change Summary")})})}),e.jsx("div",{className:t.summaryGrid,children:$.map(i=>{const c=a.changeSummary;let o;switch(i.key){case"script":o=c.scriptsModified+c.scriptsCreated;break;case"instance":o=c.instancesCreated+c.instancesDeleted+c.instancesMoved;break;case"property":o=c.propertiesChanged;break;case"lighting":o=c.lightingChanged?1:0;break;case"terrain":o=c.terrainChanged?1:0;break;case"asset":o=c.assetsInserted;break;default:o=0}const K=d===i.key;return e.jsxs("div",{className:`${t.summaryCard} ${K?t.summaryCardActive:""}`,onClick:()=>u(K?"all":i.key),children:[e.jsx("span",{className:t.summaryIcon,children:i.icon}),e.jsx("div",{className:t.summaryCount,children:o}),e.jsx("div",{className:t.summaryLabel,children:n(i.labelKey,i.key)})]},i.key)})})]}),L&&e.jsxs("div",{className:t.section,children:[e.jsx("div",{className:t.sectionTitle,children:e.jsx(m,{text:n("changelog.detail.context.tooltip","Structured execution context captured for this changelog session."),children:e.jsx("span",{children:n("changelog.detail.context.title","Context Summary")})})}),e.jsxs("div",{className:t.contextGrid,children:[((S=a.contextSummary)==null?void 0:S.intent)&&e.jsxs("div",{className:t.contextRow,children:[e.jsx("span",{className:t.contextKey,children:n("changelog.card.sessionIntent","Session intent")}),e.jsx("span",{className:t.contextValue,children:a.contextSummary.intent})]}),((C=a.contextSummary)==null?void 0:C.testScenario)&&e.jsxs("div",{className:t.contextRow,children:[e.jsx("span",{className:t.contextKey,children:n("playtest.context.why","Why this test ran")}),e.jsx("span",{className:t.contextValue,children:a.contextSummary.testScenario})]}),((N=a.contextSummary)==null?void 0:N.expectedBehavior)&&e.jsxs("div",{className:t.contextRow,children:[e.jsx("span",{className:t.contextKey,children:n("playtest.context.expected","Expected")}),e.jsx("span",{className:t.contextValue,children:a.contextSummary.expectedBehavior})]}),((T=a.contextSummary)==null?void 0:T.observedBehavior)&&e.jsxs("div",{className:t.contextRow,children:[e.jsx("span",{className:t.contextKey,children:n("playtest.context.observed","Observed")}),e.jsx("span",{className:t.contextValue,children:a.contextSummary.observedBehavior})]})]})]}),O&&e.jsxs("div",{className:t.section,children:[e.jsx("div",{className:t.sectionTitle,children:e.jsx(m,{text:n("changelog.detail.verification.tooltip","Verification signals linked to this changelog session."),children:e.jsx("span",{children:n("changelog.detail.verification.title","Verification")})})}),e.jsxs("div",{className:t.contextGrid,children:[((g=a.verificationSummary)==null?void 0:g.label)&&e.jsxs("div",{className:t.contextRow,children:[e.jsx("span",{className:t.contextKey,children:n("changelog.detail.verification.label","Result")}),e.jsx("span",{className:t.contextValue,children:a.verificationSummary.label})]}),((k=a.verificationSummary)==null?void 0:k.status)&&e.jsxs("div",{className:t.contextRow,children:[e.jsx("span",{className:t.contextKey,children:n("changelog.detail.verification.status","Status")}),e.jsx("span",{className:t.contextValue,children:a.verificationSummary.status})]}),((h=a.verificationSummary)==null?void 0:h.testTimestamp)&&e.jsxs("div",{className:t.contextRow,children:[e.jsx("span",{className:t.contextKey,children:n("changelog.detail.verification.timestamp","Recorded at")}),e.jsx("span",{className:t.contextValue,children:a.verificationSummary.testTimestamp})]})]})]}),e.jsxs("div",{className:t.section,children:[e.jsx("div",{className:t.sectionTitle,children:e.jsx(m,{text:n("changelog.detail.changeTimeline.tooltip","Chronological list of extracted game changes for this session."),children:e.jsx("span",{children:n("changelog.detail.changeTimeline","Change Timeline")})})}),e.jsxs("div",{className:t.timelineFilter,children:[e.jsx("span",{className:t.filterLabel,children:e.jsx(G,{label:`${n("changelog.detail.filterCategory","Category")}:`,tooltip:n("changelog.detail.filterCategory.tooltip","Filter the timeline to a single change category.")})}),e.jsxs("select",{className:t.filterSelect,value:d,onChange:i=>u(i.target.value),children:[e.jsx("option",{value:"all",children:n("tools.filter.all","All")}),$.map(i=>e.jsxs("option",{value:i.key,children:[i.icon," ",n(i.labelKey,i.key)]},i.key))]})]}),y.length===0?e.jsx("div",{className:t.empty,children:n("changelog.detail.noChanges","No changes in this category")}):e.jsx("div",{className:t.timeline,children:y.map((i,c)=>{const o=q===c;return e.jsxs("div",{children:[e.jsxs("div",{className:t.timelineEntry,onClick:()=>w(o?null:c),children:[e.jsx("span",{className:t.timelineTime,children:Le(i.timestamp)}),e.jsx("span",{className:t.timelineIcon,children:H(i.category)}),e.jsxs("div",{className:t.timelineBody,children:[e.jsxs("div",{className:t.timelineSummary,children:[i.summary,e.jsx(m,{text:Re(n,i.confidence),children:e.jsx("span",{className:`${t.timelineConfidence} ${Ae(i.confidence)}`,children:Ke(n,i.confidence)})})]}),e.jsx("div",{className:t.timelineTarget,children:i.target})]})]}),o&&e.jsx("div",{className:t.timelineExpanded,children:e.jsx(D,{change:i})})]},c)})})]})]})}export{Ge as Component};
1
+ import{r,a as R,u as M,b as B,c as V,j as e}from"./index-C9gmLH8z.js";import{I as G}from"./InfoLabel-Bp3j_i44.js";import{G as D}from"./GameChangeDetail-D31gfmkK.js";import{T as m}from"./TooltipText-Bgk-NYKr.js";function F(n){const s={scriptsModified:0,scriptsCreated:0,instancesCreated:0,instancesDeleted:0,instancesMoved:0,propertiesChanged:0,lightingChanged:!1,terrainChanged:!1,assetsInserted:0};for(const l of n)switch(l.category){case"script":l.changeType==="create"?s.scriptsCreated++:s.scriptsModified++;break;case"instance":l.changeType==="create"?s.instancesCreated++:l.changeType==="delete"?s.instancesDeleted++:l.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 P(n){const[s,l]=r.useState(""),[a,d]=r.useState(""),[u,q]=r.useState(),[w,y]=r.useState("completed"),[I,E]=r.useState([]),[L,O]=r.useState([]),[x,f]=r.useState([]),[p,_]=r.useState(),[j,b]=r.useState(),[v,S]=r.useState(),[C,N]=r.useState({scriptsModified:0,scriptsCreated:0,instancesCreated:0,instancesDeleted:0,instancesMoved:0,propertiesChanged:0,lightingChanged:!1,terrainChanged:!1,assetsInserted:0}),[T,g]=r.useState(!0),[k,h]=r.useState(null),i=r.useCallback(async()=>{if(n){g(!0),h(null);try{const[c,o]=await Promise.all([R.get(`/api/dashboard/changelog/${n}`),R.get(`/api/dashboard/changelog/${n}/changes`)]);l(c.entryId),d(c.startTime),q(c.endTime),y(c.status),E(c.entries),O(c.failures),_(c.contextSummary),b(c.replayMetadata),S(c.verificationSummary),f(o.changes),N(F(o.changes))}catch(c){h(c instanceof Error?c.message:"Failed to load changelog detail")}finally{g(!1)}}},[n]);return r.useEffect(()=>{i()},[i]),{entryId:s,startTime:a,endTime:u,status:w,entries:I,failures:L,changes:x,changeSummary:C,contextSummary:p,replayMetadata:j,verificationSummary:v,loading:T,error:k,refresh:i}}const U={script:"📝",instance:"🧱",property:"🎨",lighting:"🌅",terrain:"⛰️",asset:"📦"};function H(n){return U[n]??"❓"}const W="_page_q2jbi_2",Y="_header_q2jbi_10",z="_backLink_q2jbi_16",J="_headerTitle_q2jbi_29",Q="_headerTime_q2jbi_37",X="_statusActive_q2jbi_44",Z="_statusCompleted_q2jbi_49",ee="_section_q2jbi_54",te="_sectionTitle_q2jbi_61",ne="_summaryGrid_q2jbi_74",ae="_summaryCard_q2jbi_80",ie="_summaryCardActive_q2jbi_94",se="_summaryIcon_q2jbi_99",ce="_summaryCount_q2jbi_105",re="_summaryLabel_q2jbi_112",oe="_contextGrid_q2jbi_121",le="_contextRow_q2jbi_127",de="_contextKey_q2jbi_133",me="_contextValue_q2jbi_141",ge="_timelineFilter_q2jbi_149",he="_filterLabel_q2jbi_156",ue="_filterSelect_q2jbi_162",ye="_timeline_q2jbi_149",xe="_timelineEntry_q2jbi_182",fe="_timelineTime_q2jbi_199",pe="_timelineIcon_q2jbi_207",_e="_timelineBody_q2jbi_212",je="_timelineSummary_q2jbi_217",be="_timelineTarget_q2jbi_224",ve="_timelineConfidence_q2jbi_231",Se="_confidenceExact_q2jbi_240",Ce="_confidencePartial_q2jbi_245",Ne="_confidenceAfterOnly_q2jbi_250",Te="_confidenceIntentOnly_q2jbi_255",ke="_confidenceUnknown_q2jbi_260",qe="_timelineExpanded_q2jbi_266",we="_empty_q2jbi_338",Ie="_loading_q2jbi_347",Ee="_error_q2jbi_356",t={page:W,header:Y,backLink:z,headerTitle:J,headerTime:Q,statusActive:X,statusCompleted:Z,section:ee,sectionTitle:te,summaryGrid:ne,summaryCard:ae,summaryCardActive:ie,summaryIcon:se,summaryCount:ce,summaryLabel:re,contextGrid:oe,contextRow:le,contextKey:de,contextValue:me,timelineFilter:ge,filterLabel:he,filterSelect:ue,timeline:ye,timelineEntry:xe,timelineTime:fe,timelineIcon:pe,timelineBody:_e,timelineSummary:je,timelineTarget:be,timelineConfidence:ve,confidenceExact:Se,confidencePartial:Ce,confidenceAfterOnly:Ne,confidenceIntentOnly:Te,confidenceUnknown:ke,timelineExpanded:qe,empty:we,loading:Ie,error:Ee},$=[{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 A(n){if(!n)return"--:--";const s=new Date(n);return`${String(s.getHours()).padStart(2,"0")}:${String(s.getMinutes()).padStart(2,"0")}`}function Le(n){if(!n)return"--:--:--";const s=new Date(n);return`${String(s.getHours()).padStart(2,"0")}:${String(s.getMinutes()).padStart(2,"0")}:${String(s.getSeconds()).padStart(2,"0")}`}function Oe(n,s){if(!n||!s)return"";const l=new Date(s).getTime()-new Date(n).getTime();return l<0?"":`${Math.round(l/6e4)}min`}function Ae(n){switch(n){case"exact":return t.confidenceExact;case"partial":return t.confidencePartial;case"after-only":return t.confidenceAfterOnly;case"intent-only":return t.confidenceIntentOnly;default:return t.confidenceUnknown}}function Ke(n,s){switch(s){case"exact":return n("changelog.detail.confidence.exact","Exact");case"partial":return n("changelog.detail.confidence.partial","Partial");case"after-only":return n("changelog.detail.confidence.afterOnly","After only");case"intent-only":return n("changelog.detail.confidence.intentOnly","Intent only");default:return n("changelog.detail.confidence.unknown","Unknown")}}function Re(n,s){switch(s){case"exact":return n("changelog.detail.confidence.exact.tooltip","Both the before and after state were confirmed for this change.");case"partial":return n("changelog.detail.confidence.partial.tooltip","Only part of the before and after state could be confirmed for this change.");case"after-only":return n("changelog.detail.confidence.afterOnly.tooltip","Only the resulting state after the change could be confirmed.");case"intent-only":return n("changelog.detail.confidence.intentOnly.tooltip","Only the requested action was recorded, not the resulting state.");default:return n("changelog.detail.confidence.unknown.tooltip","This change could not be confidently classified from the available data.")}}function Ge(){var x,f,p,_,j,b,v,S,C,N,T,g,k,h;const{t:n}=M(),{id:s}=B(),l=V(),a=P(s),[d,u]=r.useState("all"),[q,w]=r.useState(null),y=r.useMemo(()=>[...d==="all"?a.changes:a.changes.filter(c=>c.category===d)].reverse(),[a.changes,d]);if(a.loading)return e.jsx("div",{className:t.loading,children:n("common.loading","Loading...")});if(a.error)return e.jsxs("div",{className:t.error,children:[a.error,e.jsx("br",{}),e.jsxs("span",{className:t.backLink,onClick:()=>l("/changelog"),children:["←"," ",n("changelog.detail.backToList","Back to list")]})]});const I=Oe(a.startTime,a.endTime),E=a.endTime?`${A(a.startTime)} → ${A(a.endTime)} (${I})`:`${A(a.startTime)} → ${n("changelog.card.inProgress","in progress")}`,L=!!((x=a.contextSummary)!=null&&x.intent||(f=a.contextSummary)!=null&&f.testScenario||(p=a.contextSummary)!=null&&p.expectedBehavior||(_=a.contextSummary)!=null&&_.observedBehavior),O=!!((j=a.verificationSummary)!=null&&j.label||(b=a.verificationSummary)!=null&&b.status||(v=a.verificationSummary)!=null&&v.testTimestamp);return e.jsxs("div",{className:t.page,children:[e.jsxs("div",{className:t.header,children:[e.jsxs("span",{className:t.backLink,onClick:()=>l("/changelog"),children:["←"," ",n("sidebar.changelog","Changelog")]}),e.jsx("span",{className:t.headerTitle,children:"|"}),e.jsx("span",{className:t.headerTime,children:E}),e.jsx(m,{text:a.status==="active"?n("changelog.card.active.tooltip","This session is still receiving new game changes."):n("changelog.card.completed.tooltip","This session has ended and no more changes are expected."),children:e.jsx("span",{className:a.status==="active"?t.statusActive:t.statusCompleted,children:a.status==="active"?n("changelog.card.active","Active"):n("changelog.card.completed","Completed")})})]}),e.jsxs("div",{className:t.section,children:[e.jsx("div",{className:t.sectionTitle,children:e.jsx(m,{text:n("changelog.detail.changeSummary.tooltip","Counts of extracted game changes grouped by category for this session."),children:e.jsx("span",{children:n("changelog.detail.changeSummary","Change Summary")})})}),e.jsx("div",{className:t.summaryGrid,children:$.map(i=>{const c=a.changeSummary;let o;switch(i.key){case"script":o=c.scriptsModified+c.scriptsCreated;break;case"instance":o=c.instancesCreated+c.instancesDeleted+c.instancesMoved;break;case"property":o=c.propertiesChanged;break;case"lighting":o=c.lightingChanged?1:0;break;case"terrain":o=c.terrainChanged?1:0;break;case"asset":o=c.assetsInserted;break;default:o=0}const K=d===i.key;return e.jsxs("div",{className:`${t.summaryCard} ${K?t.summaryCardActive:""}`,onClick:()=>u(K?"all":i.key),children:[e.jsx("span",{className:t.summaryIcon,children:i.icon}),e.jsx("div",{className:t.summaryCount,children:o}),e.jsx("div",{className:t.summaryLabel,children:n(i.labelKey,i.key)})]},i.key)})})]}),L&&e.jsxs("div",{className:t.section,children:[e.jsx("div",{className:t.sectionTitle,children:e.jsx(m,{text:n("changelog.detail.context.tooltip","Structured execution context captured for this changelog session."),children:e.jsx("span",{children:n("changelog.detail.context.title","Context Summary")})})}),e.jsxs("div",{className:t.contextGrid,children:[((S=a.contextSummary)==null?void 0:S.intent)&&e.jsxs("div",{className:t.contextRow,children:[e.jsx("span",{className:t.contextKey,children:n("changelog.card.sessionIntent","Session intent")}),e.jsx("span",{className:t.contextValue,children:a.contextSummary.intent})]}),((C=a.contextSummary)==null?void 0:C.testScenario)&&e.jsxs("div",{className:t.contextRow,children:[e.jsx("span",{className:t.contextKey,children:n("playtest.context.why","Why this test ran")}),e.jsx("span",{className:t.contextValue,children:a.contextSummary.testScenario})]}),((N=a.contextSummary)==null?void 0:N.expectedBehavior)&&e.jsxs("div",{className:t.contextRow,children:[e.jsx("span",{className:t.contextKey,children:n("playtest.context.expected","Expected")}),e.jsx("span",{className:t.contextValue,children:a.contextSummary.expectedBehavior})]}),((T=a.contextSummary)==null?void 0:T.observedBehavior)&&e.jsxs("div",{className:t.contextRow,children:[e.jsx("span",{className:t.contextKey,children:n("playtest.context.observed","Observed")}),e.jsx("span",{className:t.contextValue,children:a.contextSummary.observedBehavior})]})]})]}),O&&e.jsxs("div",{className:t.section,children:[e.jsx("div",{className:t.sectionTitle,children:e.jsx(m,{text:n("changelog.detail.verification.tooltip","Verification signals linked to this changelog session."),children:e.jsx("span",{children:n("changelog.detail.verification.title","Verification")})})}),e.jsxs("div",{className:t.contextGrid,children:[((g=a.verificationSummary)==null?void 0:g.label)&&e.jsxs("div",{className:t.contextRow,children:[e.jsx("span",{className:t.contextKey,children:n("changelog.detail.verification.label","Result")}),e.jsx("span",{className:t.contextValue,children:a.verificationSummary.label})]}),((k=a.verificationSummary)==null?void 0:k.status)&&e.jsxs("div",{className:t.contextRow,children:[e.jsx("span",{className:t.contextKey,children:n("changelog.detail.verification.status","Status")}),e.jsx("span",{className:t.contextValue,children:a.verificationSummary.status})]}),((h=a.verificationSummary)==null?void 0:h.testTimestamp)&&e.jsxs("div",{className:t.contextRow,children:[e.jsx("span",{className:t.contextKey,children:n("changelog.detail.verification.timestamp","Recorded at")}),e.jsx("span",{className:t.contextValue,children:a.verificationSummary.testTimestamp})]})]})]}),e.jsxs("div",{className:t.section,children:[e.jsx("div",{className:t.sectionTitle,children:e.jsx(m,{text:n("changelog.detail.changeTimeline.tooltip","Chronological list of extracted game changes for this session."),children:e.jsx("span",{children:n("changelog.detail.changeTimeline","Change Timeline")})})}),e.jsxs("div",{className:t.timelineFilter,children:[e.jsx("span",{className:t.filterLabel,children:e.jsx(G,{label:`${n("changelog.detail.filterCategory","Category")}:`,tooltip:n("changelog.detail.filterCategory.tooltip","Filter the timeline to a single change category.")})}),e.jsxs("select",{className:t.filterSelect,value:d,onChange:i=>u(i.target.value),children:[e.jsx("option",{value:"all",children:n("tools.filter.all","All")}),$.map(i=>e.jsxs("option",{value:i.key,children:[i.icon," ",n(i.labelKey,i.key)]},i.key))]})]}),y.length===0?e.jsx("div",{className:t.empty,children:n("changelog.detail.noChanges","No changes in this category")}):e.jsx("div",{className:t.timeline,children:y.map((i,c)=>{const o=q===c;return e.jsxs("div",{children:[e.jsxs("div",{className:t.timelineEntry,onClick:()=>w(o?null:c),children:[e.jsx("span",{className:t.timelineTime,children:Le(i.timestamp)}),e.jsx("span",{className:t.timelineIcon,children:H(i.category)}),e.jsxs("div",{className:t.timelineBody,children:[e.jsxs("div",{className:t.timelineSummary,children:[i.summary,e.jsx(m,{text:Re(n,i.confidence),children:e.jsx("span",{className:`${t.timelineConfidence} ${Ae(i.confidence)}`,children:Ke(n,i.confidence)})})]}),e.jsx("div",{className:t.timelineTarget,children:i.target})]})]}),o&&e.jsx("div",{className:t.timelineExpanded,children:e.jsx(D,{change:i})})]},c)})})]})]})}export{Ge as Component};
@@ -1 +1 @@
1
- import{r as l,a as A,D as O,u as R,j as e,i as P,c as V,l as K,m as G}from"./index-BPIBy2lU.js";import{C as H}from"./ConfirmModal-Cpk7SbKb.js";import{T as $}from"./TooltipText-DX5jnyNF.js";import{T as U}from"./Tabs-BsTVkBUh.js";const Z=10;function q(){const[s,p]=l.useState([]),[t,n]=l.useState(0),[a,u]=l.useState(!1),[r,_]=l.useState(!0),[i,b]=l.useState(0),[g,x]=l.useState("all"),v=l.useRef(null),f=l.useCallback(async(d,y)=>{_(!0);try{const j={limit:String(Z),offset:String(d)};y!=="all"&&(j.status=y);const N=await A.get("/api/dashboard/changelog",j);p(N.entries),n(N.total),u(N.hasMore)}catch{p([]),n(0),u(!1)}finally{_(!1)}},[]),C=l.useCallback(()=>{f(i,g)},[f,i,g]),c=l.useCallback(async()=>{await A.post("/api/dashboard/changelog/clear"),p([]),n(0),u(!1)},[]);return l.useEffect(()=>{f(i,g)},[f,i,g]),l.useEffect(()=>{const d=new O;v.current=d,d.connect();const y=d.on("command",()=>{f(i,g)});return()=>{y(),d.disconnect(),v.current=null}},[f,i,g]),{entries:s,total:t,hasMore:a,loading:r,offset:i,statusFilter:g,setOffset:b,setStatusFilter:x,refresh:C,clear:c}}const z="_card_1n89u_2",J="_header_1n89u_17",Q="_statusBadge_1n89u_24",W="_statusDot_1n89u_35",X="_active_1n89u_41",Y="_completed_1n89u_50",ee="_timeRange_1n89u_58",te="_summaryList_1n89u_65",se="_summaryItem_1n89u_71",ae="_summaryIcon_1n89u_80",ne="_summaryText_1n89u_86",oe="_progressBar_1n89u_91",ce="_progressFill_1n89u_99",ie="_emptySummary_1n89u_112",le="_contextBlock_1n89u_120",re="_contextLabel_1n89u_129",ge="_contextValue_1n89u_137",o={card:z,header:J,statusBadge:Q,statusDot:W,active:X,completed:Y,timeRange:ee,summaryList:te,summaryItem:se,summaryIcon:ae,summaryText:ne,progressBar:oe,progressFill:ce,emptySummary:ie,contextBlock:le,contextLabel:re,contextValue:ge};function D(s){if(!s)return"--:--";const p=new Date(s);return`${String(p.getHours()).padStart(2,"0")}:${String(p.getMinutes()).padStart(2,"0")}`}function de({entry:s,onClick:p}){var j,N,I,k,w,B,L,M,E,F;const{t}=R(),n=s.changeSummary,a=s.status==="active",u=s.isBootstrapOnly===!0,r=[],_=n.scriptsModified+n.scriptsCreated;if(_>0){const m=[];n.scriptsModified>0&&m.push(`${n.scriptsModified} ${t("changelog.card.modified","modified")}`),n.scriptsCreated>0&&m.push(`${n.scriptsCreated} ${t("changelog.card.created","created")}`);const S=`${_} ${t("changelog.card.scripts","scripts")} ${m.join(", ")}`;r.push({icon:"📝",text:S,tooltip:t("changelog.card.scripts.tooltip","Script changes made in this session.")})}const i=n.instancesCreated+n.instancesDeleted+n.instancesMoved;if(i>0){const m=[];n.instancesCreated>0&&m.push(`${n.instancesCreated} ${t("changelog.card.created","created")}`),n.instancesDeleted>0&&m.push(`${n.instancesDeleted} ${t("changelog.card.deleted","deleted")}`),n.instancesMoved>0&&m.push(`${n.instancesMoved} ${t("changelog.card.moved","moved")}`);const S=`${i} ${t("changelog.card.instances","instances")} ${m.join(", ")}`;r.push({icon:"🧱",text:S,tooltip:t("changelog.card.instances.tooltip","Instance create, delete, move, or clone changes in this session.")})}n.propertiesChanged>0&&r.push({icon:"🎨",text:`${n.propertiesChanged} ${t("changelog.card.propertiesChanged","properties changed")}`,tooltip:t("changelog.card.propertiesChanged.tooltip","Property value changes recorded for this session.")}),n.lightingChanged&&r.push({icon:"🌅",text:t("changelog.card.lightingConfigured","Lighting configured"),tooltip:t("changelog.card.lightingConfigured.tooltip","Lighting or atmosphere settings changed in this session.")}),n.terrainChanged&&r.push({icon:"⛰️",text:t("changelog.card.terrainConfigured","Terrain configured"),tooltip:t("changelog.card.terrainConfigured.tooltip","Terrain data or terrain settings changed in this session.")}),n.assetsInserted>0&&r.push({icon:"📦",text:`${n.assetsInserted} ${t("changelog.card.assetsInserted","assets inserted")}`,tooltip:t("changelog.card.assetsInserted.tooltip","Assets inserted into the place during this session.")});const b=D(s.startTime),g=a?t("changelog.card.inProgress","in progress"):s.endTime?D(s.endTime):"--:--",x=u?t("changelog.card.bootstrapStatus","Bootstrap"):a?t("changelog.card.active","Active"):t("changelog.card.completed","Completed"),v=u?t("changelog.card.bootstrapStatus.tooltip","This session only contains the initial sync bootstrap snapshot."):a?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."),f=u?t("changelog.card.bootstrapSummary","Initial sync snapshot"):t("changelog.card.noChanges","No changes yet"),C=u?t("changelog.card.bootstrapSummary.tooltip","Initial file sync writes are collapsed into a single bootstrap snapshot row."):t("changelog.card.noChanges.tooltip","No game changes have been extracted for this session yet."),c=(N=(j=s.contextSummary)==null?void 0:j.intent)==null?void 0:N.trim(),d=((B=(w=(k=(I=s.contextSummary)==null?void 0:I.affectedAreas)==null?void 0:k[0])==null?void 0:w.label)==null?void 0:B.trim())||((M=(L=s.contextSummary)==null?void 0:L.testScenario)==null?void 0:M.trim()),y=(F=(E=s.verificationSummary)==null?void 0:E.label)==null?void 0:F.trim();return e.jsxs("div",{className:o.card,onClick:p,children:[e.jsxs("div",{className:o.header,children:[e.jsx($,{text:v,children:e.jsxs("span",{className:`${o.statusBadge} ${a?o.active:o.completed}`,children:[e.jsx("span",{className:o.statusDot}),x]})}),e.jsxs("span",{className:o.timeRange,children:[b,"~",g]})]}),e.jsx("div",{className:o.summaryList,children:r.length>0?r.map((m,S)=>e.jsxs("div",{className:o.summaryItem,children:[e.jsx("span",{className:o.summaryIcon,children:m.icon}),e.jsx($,{text:m.tooltip,children:e.jsx("span",{className:o.summaryText,children:m.text})})]},S)):e.jsx($,{text:C,children:e.jsx("span",{className:o.emptySummary,style:{display:"block"},children:f})})}),c&&e.jsxs("div",{className:o.contextBlock,children:[e.jsx("span",{className:o.contextLabel,children:t("changelog.card.sessionIntent","Session intent")}),e.jsx("span",{className:o.contextValue,children:c})]}),!c&&d&&e.jsxs("div",{className:o.contextBlock,children:[e.jsx("span",{className:o.contextLabel,children:t("changelog.card.representativeArea","Representative area")}),e.jsx("span",{className:o.contextValue,children:d})]}),y&&e.jsxs("div",{className:o.contextBlock,children:[e.jsx("span",{className:o.contextLabel,children:t("changelog.card.verification","Verification")}),e.jsx("span",{className:o.contextValue,children:y})]}),a&&e.jsx("div",{className:o.progressBar,children:e.jsx("div",{className:o.progressFill})})]})}const me="_page_1ynbw_2",he="_limitNotice_1ynbw_9",pe="_limitNoticeTitle_1ynbw_18",ue="_limitNoticeText_1ynbw_25",fe="_clearButton_1ynbw_33",_e="_list_1ynbw_54",xe="_empty_1ynbw_61",ye="_loading_1ynbw_70",be="_pagination_1ynbw_79",ve="_pageInfo_1ynbw_87",Ne="_btn_1ynbw_93",h={page:me,limitNotice:he,limitNoticeTitle:pe,limitNoticeText:ue,clearButton:fe,list:_e,empty:xe,loading:ye,pagination:be,pageInfo:ve,btn:Ne},T=10,Ce=[{key:"all",labelKey:"changelog.filter.all"},{key:"active",labelKey:"changelog.filter.active"},{key:"completed",labelKey:"changelog.filter.completed"}];function Ie(){const{t:s}=R(),{trackEvent:p,trackPageView:t}=P(),n=V(),a=q(),u=K(),{show:r}=G(),[_,i]=l.useState(!1),[b,g]=l.useState(!1),x=!u.loading&&u.tier==="basic",v=x?a.entries.slice(0,3):a.entries,f=!x&&a.total>T,C=async()=>{g(!0);try{await a.clear(),r(s("toast.clearSuccess","Cleared successfully"),"success"),i(!1)}catch{r(s("toast.clearFailed","Failed to clear data"),"error")}finally{g(!1)}};return e.jsxs("div",{className:h.page,children:[e.jsx(U,{items:Ce.map(c=>({key:c.key,label:s(c.labelKey,c.key.charAt(0).toUpperCase()+c.key.slice(1))})),value:a.statusFilter,onChange:c=>{const d=`changelog_${c}`;p("dashboard_click_event",{click_target:`changelog_tab_${c}`,page:"changelog",tab:d}),t({page:"changelog",tab:d}),a.setStatusFilter(c),a.setOffset(0)},rightActions:e.jsx("button",{className:h.clearButton,onClick:()=>{p("dashboard_click_event",{click_target:"changelog_clear",page:"changelog",tab:`changelog_${a.statusFilter}`}),i(!0)},children:s("common.clear","Clear")})}),a.loading&&a.entries.length===0&&e.jsx("div",{className:h.loading,children:s("common.loading","Loading...")}),!a.loading&&a.entries.length===0?e.jsx("div",{className:h.empty,children:s("changelog.empty","No changelog entries yet")}):e.jsx("div",{className:h.list,children:v.map(c=>e.jsx(de,{entry:c,onClick:()=>n(`/changelog/${c.entryId}`)},c.entryId))}),f&&e.jsxs("div",{className:h.pagination,children:[e.jsx("button",{className:h.btn,disabled:a.offset===0,onClick:()=>a.setOffset(Math.max(0,a.offset-T)),children:s("tools.page.prev","Prev")}),e.jsxs("span",{className:h.pageInfo,children:[a.offset+1,"–",Math.min(a.offset+T,a.total)," / ",a.total]}),e.jsx("button",{className:h.btn,disabled:!a.hasMore,onClick:()=>a.setOffset(a.offset+T),children:s("tools.page.next","Next")})]}),x&&e.jsx(e.Fragment,{children:e.jsxs("div",{className:h.limitNotice,children:[e.jsx("div",{className:h.limitNoticeTitle,children:s("changelog.basic.limit.title","Basic preview shows the latest 3 sessions")}),e.jsx("div",{className:h.limitNoticeText,children:s("changelog.basic.limit.body","Upgrade to Pro to browse the full changelog timeline for this place.")})]})}),e.jsx(H,{open:_,title:s("changelog.clear.title","Clear changelog?"),message:s("changelog.clear.message","This permanently removes the stored changelog for the current place."),cancelLabel:s("common.cancel","Cancel"),confirmLabel:s("common.clear","Clear"),loading:b,onCancel:()=>!b&&i(!1),onConfirm:C})]})}export{Ie as Component};
1
+ import{r as l,a as A,D as O,u as R,j as e,i as P,c as V,l as K,m as G}from"./index-C9gmLH8z.js";import{C as H}from"./ConfirmModal-Dg8_uxRE.js";import{T as $}from"./TooltipText-Bgk-NYKr.js";import{T as U}from"./Tabs-BCiSXsKz.js";const Z=10;function q(){const[s,p]=l.useState([]),[t,n]=l.useState(0),[a,u]=l.useState(!1),[r,_]=l.useState(!0),[i,b]=l.useState(0),[g,x]=l.useState("all"),v=l.useRef(null),f=l.useCallback(async(d,y)=>{_(!0);try{const j={limit:String(Z),offset:String(d)};y!=="all"&&(j.status=y);const N=await A.get("/api/dashboard/changelog",j);p(N.entries),n(N.total),u(N.hasMore)}catch{p([]),n(0),u(!1)}finally{_(!1)}},[]),C=l.useCallback(()=>{f(i,g)},[f,i,g]),c=l.useCallback(async()=>{await A.post("/api/dashboard/changelog/clear"),p([]),n(0),u(!1)},[]);return l.useEffect(()=>{f(i,g)},[f,i,g]),l.useEffect(()=>{const d=new O;v.current=d,d.connect();const y=d.on("command",()=>{f(i,g)});return()=>{y(),d.disconnect(),v.current=null}},[f,i,g]),{entries:s,total:t,hasMore:a,loading:r,offset:i,statusFilter:g,setOffset:b,setStatusFilter:x,refresh:C,clear:c}}const z="_card_1n89u_2",J="_header_1n89u_17",Q="_statusBadge_1n89u_24",W="_statusDot_1n89u_35",X="_active_1n89u_41",Y="_completed_1n89u_50",ee="_timeRange_1n89u_58",te="_summaryList_1n89u_65",se="_summaryItem_1n89u_71",ae="_summaryIcon_1n89u_80",ne="_summaryText_1n89u_86",oe="_progressBar_1n89u_91",ce="_progressFill_1n89u_99",ie="_emptySummary_1n89u_112",le="_contextBlock_1n89u_120",re="_contextLabel_1n89u_129",ge="_contextValue_1n89u_137",o={card:z,header:J,statusBadge:Q,statusDot:W,active:X,completed:Y,timeRange:ee,summaryList:te,summaryItem:se,summaryIcon:ae,summaryText:ne,progressBar:oe,progressFill:ce,emptySummary:ie,contextBlock:le,contextLabel:re,contextValue:ge};function D(s){if(!s)return"--:--";const p=new Date(s);return`${String(p.getHours()).padStart(2,"0")}:${String(p.getMinutes()).padStart(2,"0")}`}function de({entry:s,onClick:p}){var j,N,I,k,w,B,L,M,E,F;const{t}=R(),n=s.changeSummary,a=s.status==="active",u=s.isBootstrapOnly===!0,r=[],_=n.scriptsModified+n.scriptsCreated;if(_>0){const m=[];n.scriptsModified>0&&m.push(`${n.scriptsModified} ${t("changelog.card.modified","modified")}`),n.scriptsCreated>0&&m.push(`${n.scriptsCreated} ${t("changelog.card.created","created")}`);const S=`${_} ${t("changelog.card.scripts","scripts")} ${m.join(", ")}`;r.push({icon:"📝",text:S,tooltip:t("changelog.card.scripts.tooltip","Script changes made in this session.")})}const i=n.instancesCreated+n.instancesDeleted+n.instancesMoved;if(i>0){const m=[];n.instancesCreated>0&&m.push(`${n.instancesCreated} ${t("changelog.card.created","created")}`),n.instancesDeleted>0&&m.push(`${n.instancesDeleted} ${t("changelog.card.deleted","deleted")}`),n.instancesMoved>0&&m.push(`${n.instancesMoved} ${t("changelog.card.moved","moved")}`);const S=`${i} ${t("changelog.card.instances","instances")} ${m.join(", ")}`;r.push({icon:"🧱",text:S,tooltip:t("changelog.card.instances.tooltip","Instance create, delete, move, or clone changes in this session.")})}n.propertiesChanged>0&&r.push({icon:"🎨",text:`${n.propertiesChanged} ${t("changelog.card.propertiesChanged","properties changed")}`,tooltip:t("changelog.card.propertiesChanged.tooltip","Property value changes recorded for this session.")}),n.lightingChanged&&r.push({icon:"🌅",text:t("changelog.card.lightingConfigured","Lighting configured"),tooltip:t("changelog.card.lightingConfigured.tooltip","Lighting or atmosphere settings changed in this session.")}),n.terrainChanged&&r.push({icon:"⛰️",text:t("changelog.card.terrainConfigured","Terrain configured"),tooltip:t("changelog.card.terrainConfigured.tooltip","Terrain data or terrain settings changed in this session.")}),n.assetsInserted>0&&r.push({icon:"📦",text:`${n.assetsInserted} ${t("changelog.card.assetsInserted","assets inserted")}`,tooltip:t("changelog.card.assetsInserted.tooltip","Assets inserted into the place during this session.")});const b=D(s.startTime),g=a?t("changelog.card.inProgress","in progress"):s.endTime?D(s.endTime):"--:--",x=u?t("changelog.card.bootstrapStatus","Bootstrap"):a?t("changelog.card.active","Active"):t("changelog.card.completed","Completed"),v=u?t("changelog.card.bootstrapStatus.tooltip","This session only contains the initial sync bootstrap snapshot."):a?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."),f=u?t("changelog.card.bootstrapSummary","Initial sync snapshot"):t("changelog.card.noChanges","No changes yet"),C=u?t("changelog.card.bootstrapSummary.tooltip","Initial file sync writes are collapsed into a single bootstrap snapshot row."):t("changelog.card.noChanges.tooltip","No game changes have been extracted for this session yet."),c=(N=(j=s.contextSummary)==null?void 0:j.intent)==null?void 0:N.trim(),d=((B=(w=(k=(I=s.contextSummary)==null?void 0:I.affectedAreas)==null?void 0:k[0])==null?void 0:w.label)==null?void 0:B.trim())||((M=(L=s.contextSummary)==null?void 0:L.testScenario)==null?void 0:M.trim()),y=(F=(E=s.verificationSummary)==null?void 0:E.label)==null?void 0:F.trim();return e.jsxs("div",{className:o.card,onClick:p,children:[e.jsxs("div",{className:o.header,children:[e.jsx($,{text:v,children:e.jsxs("span",{className:`${o.statusBadge} ${a?o.active:o.completed}`,children:[e.jsx("span",{className:o.statusDot}),x]})}),e.jsxs("span",{className:o.timeRange,children:[b,"~",g]})]}),e.jsx("div",{className:o.summaryList,children:r.length>0?r.map((m,S)=>e.jsxs("div",{className:o.summaryItem,children:[e.jsx("span",{className:o.summaryIcon,children:m.icon}),e.jsx($,{text:m.tooltip,children:e.jsx("span",{className:o.summaryText,children:m.text})})]},S)):e.jsx($,{text:C,children:e.jsx("span",{className:o.emptySummary,style:{display:"block"},children:f})})}),c&&e.jsxs("div",{className:o.contextBlock,children:[e.jsx("span",{className:o.contextLabel,children:t("changelog.card.sessionIntent","Session intent")}),e.jsx("span",{className:o.contextValue,children:c})]}),!c&&d&&e.jsxs("div",{className:o.contextBlock,children:[e.jsx("span",{className:o.contextLabel,children:t("changelog.card.representativeArea","Representative area")}),e.jsx("span",{className:o.contextValue,children:d})]}),y&&e.jsxs("div",{className:o.contextBlock,children:[e.jsx("span",{className:o.contextLabel,children:t("changelog.card.verification","Verification")}),e.jsx("span",{className:o.contextValue,children:y})]}),a&&e.jsx("div",{className:o.progressBar,children:e.jsx("div",{className:o.progressFill})})]})}const me="_page_1ynbw_2",he="_limitNotice_1ynbw_9",pe="_limitNoticeTitle_1ynbw_18",ue="_limitNoticeText_1ynbw_25",fe="_clearButton_1ynbw_33",_e="_list_1ynbw_54",xe="_empty_1ynbw_61",ye="_loading_1ynbw_70",be="_pagination_1ynbw_79",ve="_pageInfo_1ynbw_87",Ne="_btn_1ynbw_93",h={page:me,limitNotice:he,limitNoticeTitle:pe,limitNoticeText:ue,clearButton:fe,list:_e,empty:xe,loading:ye,pagination:be,pageInfo:ve,btn:Ne},T=10,Ce=[{key:"all",labelKey:"changelog.filter.all"},{key:"active",labelKey:"changelog.filter.active"},{key:"completed",labelKey:"changelog.filter.completed"}];function Ie(){const{t:s}=R(),{trackEvent:p,trackPageView:t}=P(),n=V(),a=q(),u=K(),{show:r}=G(),[_,i]=l.useState(!1),[b,g]=l.useState(!1),x=!u.loading&&u.tier==="basic",v=x?a.entries.slice(0,3):a.entries,f=!x&&a.total>T,C=async()=>{g(!0);try{await a.clear(),r(s("toast.clearSuccess","Cleared successfully"),"success"),i(!1)}catch{r(s("toast.clearFailed","Failed to clear data"),"error")}finally{g(!1)}};return e.jsxs("div",{className:h.page,children:[e.jsx(U,{items:Ce.map(c=>({key:c.key,label:s(c.labelKey,c.key.charAt(0).toUpperCase()+c.key.slice(1))})),value:a.statusFilter,onChange:c=>{const d=`changelog_${c}`;p("dashboard_click_event",{click_target:`changelog_tab_${c}`,page:"changelog",tab:d}),t({page:"changelog",tab:d}),a.setStatusFilter(c),a.setOffset(0)},rightActions:e.jsx("button",{className:h.clearButton,onClick:()=>{p("dashboard_click_event",{click_target:"changelog_clear",page:"changelog",tab:`changelog_${a.statusFilter}`}),i(!0)},children:s("common.clear","Clear")})}),a.loading&&a.entries.length===0&&e.jsx("div",{className:h.loading,children:s("common.loading","Loading...")}),!a.loading&&a.entries.length===0?e.jsx("div",{className:h.empty,children:s("changelog.empty","No changelog entries yet")}):e.jsx("div",{className:h.list,children:v.map(c=>e.jsx(de,{entry:c,onClick:()=>n(`/changelog/${c.entryId}`)},c.entryId))}),f&&e.jsxs("div",{className:h.pagination,children:[e.jsx("button",{className:h.btn,disabled:a.offset===0,onClick:()=>a.setOffset(Math.max(0,a.offset-T)),children:s("tools.page.prev","Prev")}),e.jsxs("span",{className:h.pageInfo,children:[a.offset+1,"–",Math.min(a.offset+T,a.total)," / ",a.total]}),e.jsx("button",{className:h.btn,disabled:!a.hasMore,onClick:()=>a.setOffset(a.offset+T),children:s("tools.page.next","Next")})]}),x&&e.jsx(e.Fragment,{children:e.jsxs("div",{className:h.limitNotice,children:[e.jsx("div",{className:h.limitNoticeTitle,children:s("changelog.basic.limit.title","Basic preview shows the latest 3 sessions")}),e.jsx("div",{className:h.limitNoticeText,children:s("changelog.basic.limit.body","Upgrade to Pro to browse the full changelog timeline for this place.")})]})}),e.jsx(H,{open:_,title:s("changelog.clear.title","Clear changelog?"),message:s("changelog.clear.message","This permanently removes the stored changelog for the current place."),cancelLabel:s("common.cancel","Cancel"),confirmLabel:s("common.clear","Clear"),loading:b,onCancel:()=>!b&&i(!1),onConfirm:C})]})}export{Ie as Component};
@@ -1 +1 @@
1
- import{j as s,x as e}from"./index-BPIBy2lU.js";function x({open:c,title:i,message:n,cancelLabel:t,confirmLabel:o,loading:a=!1,onCancel:l,onConfirm:r}){return c?s.jsx("div",{className:e.backdrop,onClick:a?void 0:l,children:s.jsxs("div",{className:e.modal,onClick:d=>d.stopPropagation(),children:[s.jsx("h2",{className:e.title,children:i}),s.jsx("p",{className:e.message,children:n}),s.jsxs("div",{className:e.actions,children:[s.jsx("button",{className:e.cancelButton,onClick:l,disabled:a,children:t}),s.jsx("button",{className:e.confirmButton,onClick:r,disabled:a,children:a?"...":o})]})]})}):null}export{x as C};
1
+ import{j as s,x as e}from"./index-C9gmLH8z.js";function x({open:c,title:i,message:n,cancelLabel:t,confirmLabel:o,loading:a=!1,onCancel:l,onConfirm:r}){return c?s.jsx("div",{className:e.backdrop,onClick:a?void 0:l,children:s.jsxs("div",{className:e.modal,onClick:d=>d.stopPropagation(),children:[s.jsx("h2",{className:e.title,children:i}),s.jsx("p",{className:e.message,children:n}),s.jsxs("div",{className:e.actions,children:[s.jsx("button",{className:e.cancelButton,onClick:l,disabled:a,children:t}),s.jsx("button",{className:e.confirmButton,onClick:r,disabled:a,children:a?"...":o})]})]})}):null}export{x as C};
@@ -1 +1 @@
1
- import{u as R,r as a,j as e,d as P,a as S,D as T,i as D,m as F}from"./index-BPIBy2lU.js";import{I as r}from"./InfoLabel-B_fEbHa7.js";import{S as H}from"./StatusBadge-DRdnq30k.js";import{T as U}from"./TooltipText-DX5jnyNF.js";import{C as $}from"./ConfirmModal-Cpk7SbKb.js";import{u as K,f as G}from"./useLiveUptime-ElD9lDzh.js";const O="_container_1h084_2",V="_entry_1h084_14",q="_timestamp_1h084_21",X="_message_1h084_27",z="_warn_1h084_34",J="_error_1h084_39",Q="_empty_1h084_44",v={container:O,entry:V,timestamp:q,message:X,warn:z,error:J,empty:Q};function W(n){const i=new Date(n);return Number.isNaN(i.getTime())?n:`${String(i.getHours()).padStart(2,"0")}:${String(i.getMinutes()).padStart(2,"0")}`}function Y({entries:n}){const{t:i}=R(),t=a.useRef(null);return a.useEffect(()=>{const o=t.current;o&&(o.scrollTop=o.scrollHeight)},[n.length]),e.jsx("div",{ref:t,className:v.container,children:n.length===0?e.jsx("div",{className:v.empty,children:i("connection.log.empty","No events yet")}):n.map((o,u)=>e.jsxs("div",{className:`${v.entry} ${o.type?v[o.type]:""}`,children:[e.jsx("span",{className:v.timestamp,children:W(o.timestamp)}),e.jsx("span",{className:v.message,children:o.message})]},u))})}const A=50;function Z(){const n=new Date;return`${String(n.getHours()).padStart(2,"0")}:${String(n.getMinutes()).padStart(2,"0")}`}function ee(){const{level:n,status:i,error:t}=P(),[o,u]=a.useState(null),[N,j]=a.useState([]),C=a.useRef(null),g=a.useCallback((l,x)=>{j(p=>{const d=[...p,{timestamp:Z(),message:l,type:x}];return d.length>A?d.slice(-A):d})},[]),m=a.useCallback(async()=>{try{const l=await S.get("/connection-info");u(l)}catch{u(null)}},[]),y=a.useCallback(async()=>{try{const l=await S.get("/api/dashboard/connection-log");j(l.entries??[])}catch{j([])}},[]),k=a.useCallback(async()=>{await S.post("/api/dashboard/connection-log/clear"),j([])},[]),f=a.useCallback(async l=>{await S.post("/api/dashboard/kill-agent",{instanceId:l}),await m()},[m]);return a.useEffect(()=>{n!=="disconnected"&&i&&m(),y()},[n,i,m,y]),a.useEffect(()=>{const l=new T;C.current=l,l.connect();const x=l.on("connection",d=>{const h=d,_=h.status==="connected"?"connected":"disconnected";g(`Plugin ${_} — ${h.clientId}`,h.status==="connected"?"info":"warn")}),p=l.on("mcp_status",d=>{const h=d,_=h.status==="registered"?"registered":"unregistered";g(`MCP ${_} — ${h.aiClientName}`,h.status==="registered"?"info":"warn"),m()});return()=>{x(),p(),l.disconnect(),C.current=null}},[g,m]),{status:i,connectionInfo:o,connectionLog:N,level:n,error:t,clearConnectionLog:k,killAgent:f}}const ne="_page_15jrd_2",te="_card_15jrd_10",se="_disabled_15jrd_18",ce="_cardHeader_15jrd_24",oe="_clearButton_15jrd_37",ie="_serverGrid_15jrd_47",ae="_statusRow_15jrd_65",le="_metaItem_15jrd_72",re="_table_15jrd_79",de="_toggleBtn_15jrd_104",me="_disconnected_15jrd_119",pe="_disconnectedActions_15jrd_136",he="_btn_15jrd_143",ge="_activity_active_15jrd_161",ue="_activity_stale_15jrd_162",je="_activity_unknown_15jrd_163",xe="_killBtn_15jrd_187",_e="_emptyRow_15jrd_207",s={page:ne,card:te,disabled:se,cardHeader:ce,clearButton:oe,serverGrid:ie,statusRow:ae,metaItem:le,table:re,toggleBtn:de,disconnected:me,disconnectedActions:pe,btn:he,activity_active:ge,activity_stale:ue,activity_unknown:je,killBtn:xe,emptyRow:_e};function w(n,i){const t=Math.max(0,Math.floor((Date.now()-n)/1e3));return t<60?`${t}${i("connection.time.secondsAgo","s ago")}`:t<3600?`${Math.floor(t/60)}${i("connection.time.minutesAgo","m ago")}`:`${Math.floor(t/3600)}${i("connection.time.hoursAgo","h ago")}`}function ve(n){return n?Date.now()-n<3e4?"active":"stale":"unknown"}function Ne(){var I;const{t:n}=R(),{trackEvent:i}=D(),{status:t,connectionInfo:o,connectionLog:u,level:N,clearConnectionLog:j,killAgent:C}=ee(),{show:g}=F(),[m,y]=a.useState(!0),[k,f]=a.useState(!1),[l,x]=a.useState(!1),[p,d]=a.useState(null),[h,_]=a.useState(!1),L=K(t==null?void 0:t.uptime),b=N==="disconnected",M=b?"offline":"online",E=async()=>{if(p){_(!0);try{await C(p.instanceId),g(n("connection.agents.killed","Agent killed"),"success"),d(null)}catch{g(n("connection.agents.killFailed","Failed to kill agent"),"error")}finally{_(!1)}}},B=async()=>{x(!0);try{await j(),g(n("toast.clearSuccess","Cleared successfully"),"success"),f(!1)}catch{g(n("toast.clearFailed","Failed to clear data"),"error")}finally{x(!1)}};return e.jsxs("div",{className:s.page,children:[e.jsxs("div",{className:s.card,children:[e.jsx("div",{className:s.cardHeader,children:n("connection.server.title","Server Status")}),b?e.jsxs("div",{className:s.disconnected,children:[e.jsx("h3",{children:n("level.l0.title")}),e.jsx("p",{children:n("level.l0.message")}),e.jsx("p",{children:n("common.reconnecting")}),e.jsxs("div",{className:s.disconnectedActions,children:[e.jsx("button",{className:s.btn,onClick:()=>window.location.reload(),children:n("connection.reconnect","Reconnect")}),e.jsx("button",{className:s.btn,onClick:()=>{window.location.hash="#/settings"},children:n("connection.checkSettings","Check Settings")})]})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:s.statusRow,children:e.jsx(H,{status:M})}),e.jsxs("dl",{className:s.serverGrid,children:[(t==null?void 0:t.version)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(r,{label:n("connection.server.version","Version"),tooltip:n("connection.server.version.tooltip","Installed MCP server version")})}),e.jsx("dd",{children:e.jsx(U,{text:n("connection.server.version.tooltip","Installed MCP server version"),children:`v${t.version}`})})]}),(t==null?void 0:t.pid)!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(r,{label:n("connection.server.pid","PID"),tooltip:n("connection.server.pid.tooltip","Operating system process identifier")})}),e.jsx("dd",{children:t.pid})]}),(t==null?void 0:t.uptime)!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(r,{label:n("connection.server.uptime","Uptime"),tooltip:n("connection.server.uptime.tooltip","Time elapsed since the MCP server started")})}),e.jsx("dd",{children:G(L??t.uptime)})]}),(t==null?void 0:t.sessionId)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(r,{label:n("connection.server.session","Session"),tooltip:n("connection.server.session.tooltip","Current MCP session identifier")})}),e.jsx("dd",{children:t.sessionId.slice(0,8)})]}),(o==null?void 0:o.serverExecutable)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(r,{label:n("connection.server.exec","Exec"),tooltip:n("connection.server.exec.tooltip","Executable path used to launch the MCP server")})}),e.jsx("dd",{children:o.serverExecutable})]})]})]})]}),e.jsxs("div",{className:`${s.card} ${b?s.disabled:""}`,children:[e.jsxs("div",{className:s.cardHeader,children:[e.jsxs("span",{children:[n("connection.agents.title","AI Agents")," ","(",(o==null?void 0:o.mcpInstanceCount)??0,")"]}),e.jsx("button",{className:s.toggleBtn,onClick:()=>y(c=>!c),"aria-label":m?n("common.collapse","Collapse"):n("common.expand","Expand"),children:m?"▾":"▸"})]}),m&&e.jsxs("table",{className:s.table,children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:n("connection.agents.name","Agent")}),e.jsx("th",{children:e.jsx(r,{label:n("connection.server.pid","PID"),tooltip:n("connection.server.pid.tooltip","Operating system process identifier")})}),e.jsx("th",{children:e.jsx(r,{label:n("connection.agents.projectRoot","Project Root"),tooltip:n("connection.agents.projectRoot.tooltip","Authoritative project root for sync ownership")})}),e.jsx("th",{children:n("connection.agents.connected","Connected")}),e.jsx("th",{children:e.jsx(r,{label:n("connection.agents.lastSeen","Last Seen"),tooltip:n("connection.agents.lastSeen.tooltip","Most recent heartbeat or activity from this agent")})}),e.jsx("th",{children:e.jsx(r,{label:n("connection.agents.lastCommand","Last Command"),tooltip:n("connection.agents.lastCommand.tooltip","Most recent tool call executed by this agent")})}),e.jsx("th",{})]})}),e.jsx("tbody",{children:o!=null&&o.mcpInstances&&o.mcpInstances.length>0?o.mcpInstances.map(c=>e.jsxs("tr",{children:[e.jsxs("td",{children:[e.jsx("span",{className:s[`activity_${ve(c.lastSeen)}`]}),c.aiClientName??n("connection.agents.unknown","Unknown")]}),e.jsx("td",{children:c.pid}),e.jsx("td",{children:c.projectRoot??c.cwd??n("connection.agents.projectRoot.unresolved","Unresolved")}),e.jsx("td",{children:w(c.connectedAt,n)}),e.jsx("td",{children:c.lastSeen?w(c.lastSeen,n):"-"}),e.jsx("td",{children:c.lastCommandAt?w(c.lastCommandAt,n):"-"}),e.jsx("td",{children:!c.isServer&&e.jsx("button",{className:s.killBtn,onClick:()=>{i("dashboard_click_event",{click_target:"connection_kill_agent",page:"connection"}),d({instanceId:c.instanceId,name:c.aiClientName??c.instanceId.slice(0,8)})},children:n("connection.agents.kill","Kill")})})]},c.instanceId)):e.jsx("tr",{children:e.jsx("td",{colSpan:7,className:s.emptyRow,children:n("connection.agents.none","No agents connected")})})})]})]}),e.jsxs("div",{className:`${s.card} ${b?s.disabled:""}`,children:[e.jsxs("div",{className:s.cardHeader,children:[n("connection.plugins.title","Plugins")," ","(",((I=t==null?void 0:t.pluginClients)==null?void 0:I.length)??0,")"]}),e.jsxs("table",{className:s.table,children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:n("connection.plugins.place","Place")}),e.jsx("th",{children:e.jsx(r,{label:n("connection.plugins.clientId","Client ID"),tooltip:n("connection.plugins.clientId.tooltip","Unique plugin client identifier for this Studio connection")})}),e.jsx("th",{children:e.jsx(r,{label:n("connection.plugins.lastSeen","Last Seen"),tooltip:n("connection.plugins.lastSeen.tooltip","Most recent heartbeat received from the plugin")})}),e.jsx("th",{children:e.jsx(r,{label:n("connection.plugins.version","Ver"),tooltip:n("connection.plugins.version.tooltip","Installed plugin version reported by Studio")})})]})}),e.jsx("tbody",{children:t!=null&&t.pluginClients&&t.pluginClients.length>0?t.pluginClients.map(c=>e.jsxs("tr",{children:[e.jsx("td",{children:c.placeName??c.projectName??"-"}),e.jsx("td",{children:c.clientId.slice(0,10)}),e.jsx("td",{children:w(c.lastSeen,n)}),e.jsx("td",{children:c.pluginVersion??"-"})]},c.clientId)):e.jsx("tr",{children:e.jsx("td",{colSpan:4,className:s.emptyRow,children:n("connection.plugins.none","No plugins connected")})})})]})]}),e.jsxs("div",{className:`${s.card} ${b?s.disabled:""}`,children:[e.jsxs("div",{className:s.cardHeader,children:[e.jsx("span",{children:n("connection.log.title","Connection Log")}),e.jsx("button",{className:s.clearButton,onClick:()=>{i("dashboard_click_event",{click_target:"connection_clear_log",page:"connection"}),f(!0)},children:n("common.clear","Clear")})]}),e.jsx(Y,{entries:u})]}),e.jsx($,{open:k,title:n("connection.clear.title","Clear connection log?"),message:n("connection.clear.message","This permanently removes the stored connection log for the current project."),cancelLabel:n("common.cancel","Cancel"),confirmLabel:n("common.clear","Clear"),loading:l,onCancel:()=>!l&&f(!1),onConfirm:B}),e.jsx($,{open:!!p,title:n("connection.agents.kill.title","Kill agent?"),message:`"${p==null?void 0:p.name}" 프로세스를 강제 종료합니다. 해당 에이전트의 진행 중인 작업이 중단됩니다.`,cancelLabel:n("common.cancel","Cancel"),confirmLabel:n("connection.agents.kill","Kill"),loading:h,onCancel:()=>!h&&d(null),onConfirm:E})]})}export{Ne as Component};
1
+ import{u as R,r as a,j as e,d as P,a as S,D as T,i as D,m as F}from"./index-C9gmLH8z.js";import{I as r}from"./InfoLabel-Bp3j_i44.js";import{S as H}from"./StatusBadge-4qs9buFz.js";import{T as U}from"./TooltipText-Bgk-NYKr.js";import{C as $}from"./ConfirmModal-Dg8_uxRE.js";import{u as K,f as G}from"./useLiveUptime-gW3LP94r.js";const O="_container_1h084_2",V="_entry_1h084_14",q="_timestamp_1h084_21",X="_message_1h084_27",z="_warn_1h084_34",J="_error_1h084_39",Q="_empty_1h084_44",v={container:O,entry:V,timestamp:q,message:X,warn:z,error:J,empty:Q};function W(n){const i=new Date(n);return Number.isNaN(i.getTime())?n:`${String(i.getHours()).padStart(2,"0")}:${String(i.getMinutes()).padStart(2,"0")}`}function Y({entries:n}){const{t:i}=R(),t=a.useRef(null);return a.useEffect(()=>{const o=t.current;o&&(o.scrollTop=o.scrollHeight)},[n.length]),e.jsx("div",{ref:t,className:v.container,children:n.length===0?e.jsx("div",{className:v.empty,children:i("connection.log.empty","No events yet")}):n.map((o,u)=>e.jsxs("div",{className:`${v.entry} ${o.type?v[o.type]:""}`,children:[e.jsx("span",{className:v.timestamp,children:W(o.timestamp)}),e.jsx("span",{className:v.message,children:o.message})]},u))})}const A=50;function Z(){const n=new Date;return`${String(n.getHours()).padStart(2,"0")}:${String(n.getMinutes()).padStart(2,"0")}`}function ee(){const{level:n,status:i,error:t}=P(),[o,u]=a.useState(null),[N,j]=a.useState([]),C=a.useRef(null),g=a.useCallback((l,x)=>{j(p=>{const d=[...p,{timestamp:Z(),message:l,type:x}];return d.length>A?d.slice(-A):d})},[]),m=a.useCallback(async()=>{try{const l=await S.get("/connection-info");u(l)}catch{u(null)}},[]),y=a.useCallback(async()=>{try{const l=await S.get("/api/dashboard/connection-log");j(l.entries??[])}catch{j([])}},[]),k=a.useCallback(async()=>{await S.post("/api/dashboard/connection-log/clear"),j([])},[]),f=a.useCallback(async l=>{await S.post("/api/dashboard/kill-agent",{instanceId:l}),await m()},[m]);return a.useEffect(()=>{n!=="disconnected"&&i&&m(),y()},[n,i,m,y]),a.useEffect(()=>{const l=new T;C.current=l,l.connect();const x=l.on("connection",d=>{const h=d,_=h.status==="connected"?"connected":"disconnected";g(`Plugin ${_} — ${h.clientId}`,h.status==="connected"?"info":"warn")}),p=l.on("mcp_status",d=>{const h=d,_=h.status==="registered"?"registered":"unregistered";g(`MCP ${_} — ${h.aiClientName}`,h.status==="registered"?"info":"warn"),m()});return()=>{x(),p(),l.disconnect(),C.current=null}},[g,m]),{status:i,connectionInfo:o,connectionLog:N,level:n,error:t,clearConnectionLog:k,killAgent:f}}const ne="_page_15jrd_2",te="_card_15jrd_10",se="_disabled_15jrd_18",ce="_cardHeader_15jrd_24",oe="_clearButton_15jrd_37",ie="_serverGrid_15jrd_47",ae="_statusRow_15jrd_65",le="_metaItem_15jrd_72",re="_table_15jrd_79",de="_toggleBtn_15jrd_104",me="_disconnected_15jrd_119",pe="_disconnectedActions_15jrd_136",he="_btn_15jrd_143",ge="_activity_active_15jrd_161",ue="_activity_stale_15jrd_162",je="_activity_unknown_15jrd_163",xe="_killBtn_15jrd_187",_e="_emptyRow_15jrd_207",s={page:ne,card:te,disabled:se,cardHeader:ce,clearButton:oe,serverGrid:ie,statusRow:ae,metaItem:le,table:re,toggleBtn:de,disconnected:me,disconnectedActions:pe,btn:he,activity_active:ge,activity_stale:ue,activity_unknown:je,killBtn:xe,emptyRow:_e};function w(n,i){const t=Math.max(0,Math.floor((Date.now()-n)/1e3));return t<60?`${t}${i("connection.time.secondsAgo","s ago")}`:t<3600?`${Math.floor(t/60)}${i("connection.time.minutesAgo","m ago")}`:`${Math.floor(t/3600)}${i("connection.time.hoursAgo","h ago")}`}function ve(n){return n?Date.now()-n<3e4?"active":"stale":"unknown"}function Ne(){var I;const{t:n}=R(),{trackEvent:i}=D(),{status:t,connectionInfo:o,connectionLog:u,level:N,clearConnectionLog:j,killAgent:C}=ee(),{show:g}=F(),[m,y]=a.useState(!0),[k,f]=a.useState(!1),[l,x]=a.useState(!1),[p,d]=a.useState(null),[h,_]=a.useState(!1),L=K(t==null?void 0:t.uptime),b=N==="disconnected",M=b?"offline":"online",E=async()=>{if(p){_(!0);try{await C(p.instanceId),g(n("connection.agents.killed","Agent killed"),"success"),d(null)}catch{g(n("connection.agents.killFailed","Failed to kill agent"),"error")}finally{_(!1)}}},B=async()=>{x(!0);try{await j(),g(n("toast.clearSuccess","Cleared successfully"),"success"),f(!1)}catch{g(n("toast.clearFailed","Failed to clear data"),"error")}finally{x(!1)}};return e.jsxs("div",{className:s.page,children:[e.jsxs("div",{className:s.card,children:[e.jsx("div",{className:s.cardHeader,children:n("connection.server.title","Server Status")}),b?e.jsxs("div",{className:s.disconnected,children:[e.jsx("h3",{children:n("level.l0.title")}),e.jsx("p",{children:n("level.l0.message")}),e.jsx("p",{children:n("common.reconnecting")}),e.jsxs("div",{className:s.disconnectedActions,children:[e.jsx("button",{className:s.btn,onClick:()=>window.location.reload(),children:n("connection.reconnect","Reconnect")}),e.jsx("button",{className:s.btn,onClick:()=>{window.location.hash="#/settings"},children:n("connection.checkSettings","Check Settings")})]})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:s.statusRow,children:e.jsx(H,{status:M})}),e.jsxs("dl",{className:s.serverGrid,children:[(t==null?void 0:t.version)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(r,{label:n("connection.server.version","Version"),tooltip:n("connection.server.version.tooltip","Installed MCP server version")})}),e.jsx("dd",{children:e.jsx(U,{text:n("connection.server.version.tooltip","Installed MCP server version"),children:`v${t.version}`})})]}),(t==null?void 0:t.pid)!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(r,{label:n("connection.server.pid","PID"),tooltip:n("connection.server.pid.tooltip","Operating system process identifier")})}),e.jsx("dd",{children:t.pid})]}),(t==null?void 0:t.uptime)!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(r,{label:n("connection.server.uptime","Uptime"),tooltip:n("connection.server.uptime.tooltip","Time elapsed since the MCP server started")})}),e.jsx("dd",{children:G(L??t.uptime)})]}),(t==null?void 0:t.sessionId)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(r,{label:n("connection.server.session","Session"),tooltip:n("connection.server.session.tooltip","Current MCP session identifier")})}),e.jsx("dd",{children:t.sessionId.slice(0,8)})]}),(o==null?void 0:o.serverExecutable)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(r,{label:n("connection.server.exec","Exec"),tooltip:n("connection.server.exec.tooltip","Executable path used to launch the MCP server")})}),e.jsx("dd",{children:o.serverExecutable})]})]})]})]}),e.jsxs("div",{className:`${s.card} ${b?s.disabled:""}`,children:[e.jsxs("div",{className:s.cardHeader,children:[e.jsxs("span",{children:[n("connection.agents.title","AI Agents")," ","(",(o==null?void 0:o.mcpInstanceCount)??0,")"]}),e.jsx("button",{className:s.toggleBtn,onClick:()=>y(c=>!c),"aria-label":m?n("common.collapse","Collapse"):n("common.expand","Expand"),children:m?"▾":"▸"})]}),m&&e.jsxs("table",{className:s.table,children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:n("connection.agents.name","Agent")}),e.jsx("th",{children:e.jsx(r,{label:n("connection.server.pid","PID"),tooltip:n("connection.server.pid.tooltip","Operating system process identifier")})}),e.jsx("th",{children:e.jsx(r,{label:n("connection.agents.projectRoot","Project Root"),tooltip:n("connection.agents.projectRoot.tooltip","Authoritative project root for sync ownership")})}),e.jsx("th",{children:n("connection.agents.connected","Connected")}),e.jsx("th",{children:e.jsx(r,{label:n("connection.agents.lastSeen","Last Seen"),tooltip:n("connection.agents.lastSeen.tooltip","Most recent heartbeat or activity from this agent")})}),e.jsx("th",{children:e.jsx(r,{label:n("connection.agents.lastCommand","Last Command"),tooltip:n("connection.agents.lastCommand.tooltip","Most recent tool call executed by this agent")})}),e.jsx("th",{})]})}),e.jsx("tbody",{children:o!=null&&o.mcpInstances&&o.mcpInstances.length>0?o.mcpInstances.map(c=>e.jsxs("tr",{children:[e.jsxs("td",{children:[e.jsx("span",{className:s[`activity_${ve(c.lastSeen)}`]}),c.aiClientName??n("connection.agents.unknown","Unknown")]}),e.jsx("td",{children:c.pid}),e.jsx("td",{children:c.projectRoot??c.cwd??n("connection.agents.projectRoot.unresolved","Unresolved")}),e.jsx("td",{children:w(c.connectedAt,n)}),e.jsx("td",{children:c.lastSeen?w(c.lastSeen,n):"-"}),e.jsx("td",{children:c.lastCommandAt?w(c.lastCommandAt,n):"-"}),e.jsx("td",{children:!c.isServer&&e.jsx("button",{className:s.killBtn,onClick:()=>{i("dashboard_click_event",{click_target:"connection_kill_agent",page:"connection"}),d({instanceId:c.instanceId,name:c.aiClientName??c.instanceId.slice(0,8)})},children:n("connection.agents.kill","Kill")})})]},c.instanceId)):e.jsx("tr",{children:e.jsx("td",{colSpan:7,className:s.emptyRow,children:n("connection.agents.none","No agents connected")})})})]})]}),e.jsxs("div",{className:`${s.card} ${b?s.disabled:""}`,children:[e.jsxs("div",{className:s.cardHeader,children:[n("connection.plugins.title","Plugins")," ","(",((I=t==null?void 0:t.pluginClients)==null?void 0:I.length)??0,")"]}),e.jsxs("table",{className:s.table,children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:n("connection.plugins.place","Place")}),e.jsx("th",{children:e.jsx(r,{label:n("connection.plugins.clientId","Client ID"),tooltip:n("connection.plugins.clientId.tooltip","Unique plugin client identifier for this Studio connection")})}),e.jsx("th",{children:e.jsx(r,{label:n("connection.plugins.lastSeen","Last Seen"),tooltip:n("connection.plugins.lastSeen.tooltip","Most recent heartbeat received from the plugin")})}),e.jsx("th",{children:e.jsx(r,{label:n("connection.plugins.version","Ver"),tooltip:n("connection.plugins.version.tooltip","Installed plugin version reported by Studio")})})]})}),e.jsx("tbody",{children:t!=null&&t.pluginClients&&t.pluginClients.length>0?t.pluginClients.map(c=>e.jsxs("tr",{children:[e.jsx("td",{children:c.placeName??c.projectName??"-"}),e.jsx("td",{children:c.clientId.slice(0,10)}),e.jsx("td",{children:w(c.lastSeen,n)}),e.jsx("td",{children:c.pluginVersion??"-"})]},c.clientId)):e.jsx("tr",{children:e.jsx("td",{colSpan:4,className:s.emptyRow,children:n("connection.plugins.none","No plugins connected")})})})]})]}),e.jsxs("div",{className:`${s.card} ${b?s.disabled:""}`,children:[e.jsxs("div",{className:s.cardHeader,children:[e.jsx("span",{children:n("connection.log.title","Connection Log")}),e.jsx("button",{className:s.clearButton,onClick:()=>{i("dashboard_click_event",{click_target:"connection_clear_log",page:"connection"}),f(!0)},children:n("common.clear","Clear")})]}),e.jsx(Y,{entries:u})]}),e.jsx($,{open:k,title:n("connection.clear.title","Clear connection log?"),message:n("connection.clear.message","This permanently removes the stored connection log for the current project."),cancelLabel:n("common.cancel","Cancel"),confirmLabel:n("common.clear","Clear"),loading:l,onCancel:()=>!l&&f(!1),onConfirm:B}),e.jsx($,{open:!!p,title:n("connection.agents.kill.title","Kill agent?"),message:`"${p==null?void 0:p.name}" 프로세스를 강제 종료합니다. 해당 에이전트의 진행 중인 작업이 중단됩니다.`,cancelLabel:n("common.cancel","Cancel"),confirmLabel:n("connection.agents.kill","Kill"),loading:h,onCancel:()=>!h&&d(null),onConfirm:E})]})}export{Ne as Component};
@@ -1,4 +1,4 @@
1
- import{u as _,r as x,j as e}from"./index-BPIBy2lU.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-C9gmLH8z.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,T as e}from"./index-BPIBy2lU.js";function s({label:t,tooltip:o}){return r.jsx(e,{text:o,children:t})}export{s as I};
1
+ import{j as r,T as e}from"./index-C9gmLH8z.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 P,r as v,d as G,l as L,a as M,D as F}from"./index-BPIBy2lU.js";import{I as V}from"./InfoLabel-B_fEbHa7.js";import{S as A}from"./StatusBadge-DRdnq30k.js";import{T as U}from"./TooltipText-DX5jnyNF.js";import{G as z}from"./GameChangeDetail-DM3mWsFX.js";import{u as O,f as X}from"./useLiveUptime-ElD9lDzh.js";const q="_page_1xgxh_2",J="_card_1xgxh_10",K="_cardHeader_1xgxh_17",Q="_disconnectCard_1xgxh_28",W="_disconnectIcon_1xgxh_36",Y="_disconnectTitle_1xgxh_41",Z="_disconnectMessage_1xgxh_48",ee="_reconnectGuide_1xgxh_55",te="_guideStep_1xgxh_64",se="_stepNumber_1xgxh_72",ne="_reconnectIndicator_1xgxh_88",ie="_reconnectDot_1xgxh_98",ce="_pulse_1xgxh_1",re="_disconnectActions_1xgxh_112",ae="_btn_1xgxh_118",oe="_btnSecondary_1xgxh_134",le="_metricRow_1xgxh_152",de="_metricGrid_1xgxh_158",me="_metricCard_1xgxh_164",ge="_metric_ok_1xgxh_174",he="_metric_warn_1xgxh_179",xe="_metric_error_1xgxh_184",ue="_metricHeader_1xgxh_189",ve="_metricIcon_1xgxh_200",_e="_metricTitle_1xgxh_204",pe="_metricValue_1xgxh_208",fe="_metricSubtitle_1xgxh_215",Ce="_guideCard_1xgxh_225",je="_guideTitle_1xgxh_232",we="_checklist_1xgxh_239",Ne="_feedEmpty_1xgxh_263",ye="_feedList_1xgxh_270",Te="_feedItem_1xgxh_278",Se="_feedTime_1xgxh_291",Ie="_feedIcon_1xgxh_298",be="_feedSummary_1xgxh_304",ke="_feedText_1xgxh_313",Me="_feedContext_1xgxh_321",De="_feedItemClickable_1xgxh_330",Be="_feedChevron_1xgxh_338",Ee="_feedDetail_1xgxh_347",He="_feedDetailPre_1xgxh_356",$e="_feedDetailText_1xgxh_365",Pe="_changelogSummary_1xgxh_372",Re="_changeTag_1xgxh_381",Ge="_tierBar_1xgxh_393",Le="_tierBarTrack_1xgxh_399",Fe="_tierBarFillBasic_1xgxh_407",Ve="_tierBarFillPro_1xgxh_412",Ae="_tierLabels_1xgxh_417",s={page:q,card:J,cardHeader:K,disconnectCard:Q,disconnectIcon:W,disconnectTitle:Y,disconnectMessage:Z,reconnectGuide:ee,guideStep:te,stepNumber:se,reconnectIndicator:ne,reconnectDot:ie,pulse:ce,disconnectActions:re,btn:ae,btnSecondary:oe,metricRow:le,metricGrid:de,metricCard:me,metric_ok:ge,metric_warn:he,metric_error:xe,metricHeader:ue,metricIcon:ve,metricTitle:_e,metricValue:pe,metricSubtitle:fe,guideCard:Ce,guideTitle:je,checklist:we,feedEmpty:Ne,feedList:ye,feedItem:Te,feedTime:Se,feedIcon:Ie,feedSummary:be,feedText:ke,feedContext:Me,feedItemClickable:De,feedChevron:Be,feedDetail:Ee,feedDetailPre:He,feedDetailText:$e,changelogSummary:Pe,changeTag:Re,tierBar:Ge,tierBarTrack:Le,tierBarFillBasic:Fe,tierBarFillPro:Ve,tierLabels:Ae};function j({title:e,value:i,icon:c,subtitle:r,status:o,children:n}){const l=o?s[`metric_${o}`]:"";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 Ue(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 B({changes:e}){const{t:i}=P(),[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((o,n)=>{const l=c===n,h=o.raw,m=h&&(h.before!=null||h.after!=null||h.details!=null),d=Ue(h);return t.jsxs("div",{children:[t.jsxs("div",{className:`${s.feedItem} ${m?s.feedItemClickable:""}`,onClick:()=>m&&r(l?null:n),children:[t.jsx("span",{className:s.feedTime,children:o.timestamp}),t.jsx("span",{className:s.feedIcon,children:o.icon}),t.jsxs("span",{className:s.feedText,children:[t.jsx("span",{className:s.feedSummary,children:o.summary}),d&&t.jsx("span",{className:s.feedContext,children:d})]}),m&&t.jsx("span",{className:s.feedChevron,children:l?"▴":"▾"})]}),l&&h&&t.jsx("div",{className:s.feedDetail,children:t.jsx(z,{change:h})})]},n)})})}const E=20;function R(e){return`${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`}function H(){return R(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 ze(){const{level:e,status:i}=G(),c=L(),[r,o]=v.useState(null),[n,l]=v.useState(null),[h,m]=v.useState(null),[d,w]=v.useState([]),N=v.useRef(null),S=v.useCallback(async()=>{try{const a=await M.get("/connection-info");o(a)}catch{o(null)}},[]),_=v.useCallback(async()=>{try{const a=await M.get("/api/dashboard/changelog/active");if(m(a),a.recentChanges&&a.recentChanges.length>0){const f=a.recentChanges.map(x=>({timestamp:x.timestamp?R(new Date(x.timestamp)):H(),icon:$(x.category),summary:x.summary,category:x.category,raw:x}));w(f)}}catch{m(null)}},[]),y=v.useCallback(async()=>{try{const a=await M.get("/sync/status");l(a)}catch{l(null)}},[]);return v.useEffect(()=>{e!=="disconnected"?(S(),_(),y()):(o(null),l(null),m(null));const a=new F;N.current=a,a.connect();const f=a.on("game_change",p=>{const u=p,T={timestamp:H(),icon:$(u.category),summary:u.summary,category:u.category};w(I=>{const C=[T,...I];return C.length>E?C.slice(0,E):C}),_()}),x=a.on("sync",p=>{const u=p;l(T=>({...T,state:u.status,...u.placeId?{placeId:u.placeId}:{}}))});return()=>{f(),x(),a.disconnect(),N.current=null}},[e,S,_,y]),{level:e,status:i,connectionInfo:r,syncStatus:n,changeSummary:h,recentChanges:d,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 Oe(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 Xe(e){switch(e){case"syncing":return"ok";case"initializing":return"warn";case"error":return"error";default:return"ok"}}function k(e,i,c,r){return t.jsxs("div",{className:e.metricSubtitle,children:[t.jsx(V,{label:i,tooltip:c}),": ",r]},i)}function g(e,i){return t.jsx(U,{text:i,children:e})}function Ze(){var I,C;const{t:e}=P(),{level:i,status:c,connectionInfo:r,syncStatus:o,changeSummary:n,recentChanges:l}=ze(),h=O(c==null?void 0:c.uptime);if(i==="disconnected")return t.jsx("div",{className:s.page,children: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 m=(r==null?void 0:r.mcpInstanceCount)??0,d=((I=r==null?void 0:r.mcpInstances)==null?void 0:I.find(b=>!b.isServer&&b.aiClientName))??((C=r==null?void 0:r.mcpInstances)==null?void 0:C.find(b=>!!b.aiClientName))??null,w=(c==null?void 0:c.pluginClients)??[],N=w.length>0,S=(c==null?void 0:c.sessionId)??(r==null?void 0:r.sessionId)??"-",_=e("overview.metric.server.tooltip","MCP server runtime and process status"),y=e("overview.metric.plugin.tooltip","Roblox Studio plugin connection and version status"),a=e("overview.metric.agent.tooltip","Connected AI coding agents and their runtime state"),f=e("overview.metric.sync.tooltip","Current Studio to local sync activity"),x=c?[k(s,e("overview.meta.version","Version"),e("overview.meta.version.tooltip","Installed MCP server version"),`v${c.version}`),k(s,e("overview.meta.session","Session"),e("overview.meta.session.tooltip","Current MCP session identifier"),S),k(s,e("overview.meta.pid","PID"),e("overview.meta.pid.tooltip","Operating system process identifier"),String(c.pid??"-")),k(s,e("overview.meta.uptime","Uptime"),e("overview.meta.uptime.tooltip","Time elapsed since the MCP server started"),X(h??c.uptime))]:[];if(i==="serverOnly")return t.jsxs("div",{className:s.page,children:[t.jsxs("div",{className:s.metricRow,children:[t.jsx(j,{title:g(e("overview.metric.server"),_),value:g(e("status.online"),_),icon:"🖥️",status:"ok",children:t.jsxs(t.Fragment,{children:[x,t.jsx(A,{status:"online"})]})}),t.jsx(j,{title:g(e("overview.metric.agent"),a),value:g((d==null?void 0:d.aiClientName)??e("overview.metric.noAgent"),a),icon:"🤖",subtitle:m>1?`${m} ${e("overview.metric.agent.instancesUnit","instances")}`:void 0,status:d?"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(B,{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 p=w[0],u=n?D(n):0,T=!!n&&u>0;return t.jsxs("div",{className:s.page,children:[t.jsxs("div",{className:s.metricGrid,children:[t.jsx(j,{title:g(e("overview.metric.server"),_),value:g(e("status.online"),_),icon:"🖥️",status:"ok",children:t.jsx(t.Fragment,{children:x})}),t.jsx(j,{title:g(e("overview.metric.plugin"),y),value:g(e(N?"status.online":"status.offline"),y),icon:"🔌",subtitle:p?`${p.placeName??p.projectName??"-"} / v${p.pluginVersion??"-"}`:void 0,status:N?"ok":"error"}),t.jsx(j,{title:g(e("overview.metric.agent"),a),value:g((d==null?void 0:d.aiClientName)??e("overview.metric.noAgent"),a),icon:"🤖",subtitle:m>1?`${m} ${e("overview.metric.agent.instancesUnit","instances")}`:void 0,status:d?"ok":"warn"}),t.jsx(j,{title:g(e("overview.metric.sync"),f),value:g(Oe(o==null?void 0:o.state,e),f),icon:"🔄",status:Xe(o==null?void 0:o.state)})]}),t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.feed.title")}),t.jsx(B,{changes:l})]}),T&&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"),": ",u]}),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{Ze as Component};
1
+ import{j as t,u as P,r as v,d as G,l as L,a as M,D as F}from"./index-C9gmLH8z.js";import{I as V}from"./InfoLabel-Bp3j_i44.js";import{S as A}from"./StatusBadge-4qs9buFz.js";import{T as U}from"./TooltipText-Bgk-NYKr.js";import{G as z}from"./GameChangeDetail-D31gfmkK.js";import{u as O,f as X}from"./useLiveUptime-gW3LP94r.js";const q="_page_1xgxh_2",J="_card_1xgxh_10",K="_cardHeader_1xgxh_17",Q="_disconnectCard_1xgxh_28",W="_disconnectIcon_1xgxh_36",Y="_disconnectTitle_1xgxh_41",Z="_disconnectMessage_1xgxh_48",ee="_reconnectGuide_1xgxh_55",te="_guideStep_1xgxh_64",se="_stepNumber_1xgxh_72",ne="_reconnectIndicator_1xgxh_88",ie="_reconnectDot_1xgxh_98",ce="_pulse_1xgxh_1",re="_disconnectActions_1xgxh_112",ae="_btn_1xgxh_118",oe="_btnSecondary_1xgxh_134",le="_metricRow_1xgxh_152",de="_metricGrid_1xgxh_158",me="_metricCard_1xgxh_164",ge="_metric_ok_1xgxh_174",he="_metric_warn_1xgxh_179",xe="_metric_error_1xgxh_184",ue="_metricHeader_1xgxh_189",ve="_metricIcon_1xgxh_200",_e="_metricTitle_1xgxh_204",pe="_metricValue_1xgxh_208",fe="_metricSubtitle_1xgxh_215",Ce="_guideCard_1xgxh_225",je="_guideTitle_1xgxh_232",we="_checklist_1xgxh_239",Ne="_feedEmpty_1xgxh_263",ye="_feedList_1xgxh_270",Te="_feedItem_1xgxh_278",Se="_feedTime_1xgxh_291",Ie="_feedIcon_1xgxh_298",be="_feedSummary_1xgxh_304",ke="_feedText_1xgxh_313",Me="_feedContext_1xgxh_321",De="_feedItemClickable_1xgxh_330",Be="_feedChevron_1xgxh_338",Ee="_feedDetail_1xgxh_347",He="_feedDetailPre_1xgxh_356",$e="_feedDetailText_1xgxh_365",Pe="_changelogSummary_1xgxh_372",Re="_changeTag_1xgxh_381",Ge="_tierBar_1xgxh_393",Le="_tierBarTrack_1xgxh_399",Fe="_tierBarFillBasic_1xgxh_407",Ve="_tierBarFillPro_1xgxh_412",Ae="_tierLabels_1xgxh_417",s={page:q,card:J,cardHeader:K,disconnectCard:Q,disconnectIcon:W,disconnectTitle:Y,disconnectMessage:Z,reconnectGuide:ee,guideStep:te,stepNumber:se,reconnectIndicator:ne,reconnectDot:ie,pulse:ce,disconnectActions:re,btn:ae,btnSecondary:oe,metricRow:le,metricGrid:de,metricCard:me,metric_ok:ge,metric_warn:he,metric_error:xe,metricHeader:ue,metricIcon:ve,metricTitle:_e,metricValue:pe,metricSubtitle:fe,guideCard:Ce,guideTitle:je,checklist:we,feedEmpty:Ne,feedList:ye,feedItem:Te,feedTime:Se,feedIcon:Ie,feedSummary:be,feedText:ke,feedContext:Me,feedItemClickable:De,feedChevron:Be,feedDetail:Ee,feedDetailPre:He,feedDetailText:$e,changelogSummary:Pe,changeTag:Re,tierBar:Ge,tierBarTrack:Le,tierBarFillBasic:Fe,tierBarFillPro:Ve,tierLabels:Ae};function j({title:e,value:i,icon:c,subtitle:r,status:o,children:n}){const l=o?s[`metric_${o}`]:"";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 Ue(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 B({changes:e}){const{t:i}=P(),[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((o,n)=>{const l=c===n,h=o.raw,m=h&&(h.before!=null||h.after!=null||h.details!=null),d=Ue(h);return t.jsxs("div",{children:[t.jsxs("div",{className:`${s.feedItem} ${m?s.feedItemClickable:""}`,onClick:()=>m&&r(l?null:n),children:[t.jsx("span",{className:s.feedTime,children:o.timestamp}),t.jsx("span",{className:s.feedIcon,children:o.icon}),t.jsxs("span",{className:s.feedText,children:[t.jsx("span",{className:s.feedSummary,children:o.summary}),d&&t.jsx("span",{className:s.feedContext,children:d})]}),m&&t.jsx("span",{className:s.feedChevron,children:l?"▴":"▾"})]}),l&&h&&t.jsx("div",{className:s.feedDetail,children:t.jsx(z,{change:h})})]},n)})})}const E=20;function R(e){return`${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`}function H(){return R(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 ze(){const{level:e,status:i}=G(),c=L(),[r,o]=v.useState(null),[n,l]=v.useState(null),[h,m]=v.useState(null),[d,w]=v.useState([]),N=v.useRef(null),S=v.useCallback(async()=>{try{const a=await M.get("/connection-info");o(a)}catch{o(null)}},[]),_=v.useCallback(async()=>{try{const a=await M.get("/api/dashboard/changelog/active");if(m(a),a.recentChanges&&a.recentChanges.length>0){const f=a.recentChanges.map(x=>({timestamp:x.timestamp?R(new Date(x.timestamp)):H(),icon:$(x.category),summary:x.summary,category:x.category,raw:x}));w(f)}}catch{m(null)}},[]),y=v.useCallback(async()=>{try{const a=await M.get("/sync/status");l(a)}catch{l(null)}},[]);return v.useEffect(()=>{e!=="disconnected"?(S(),_(),y()):(o(null),l(null),m(null));const a=new F;N.current=a,a.connect();const f=a.on("game_change",p=>{const u=p,T={timestamp:H(),icon:$(u.category),summary:u.summary,category:u.category};w(I=>{const C=[T,...I];return C.length>E?C.slice(0,E):C}),_()}),x=a.on("sync",p=>{const u=p;l(T=>({...T,state:u.status,...u.placeId?{placeId:u.placeId}:{}}))});return()=>{f(),x(),a.disconnect(),N.current=null}},[e,S,_,y]),{level:e,status:i,connectionInfo:r,syncStatus:n,changeSummary:h,recentChanges:d,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 Oe(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 Xe(e){switch(e){case"syncing":return"ok";case"initializing":return"warn";case"error":return"error";default:return"ok"}}function k(e,i,c,r){return t.jsxs("div",{className:e.metricSubtitle,children:[t.jsx(V,{label:i,tooltip:c}),": ",r]},i)}function g(e,i){return t.jsx(U,{text:i,children:e})}function Ze(){var I,C;const{t:e}=P(),{level:i,status:c,connectionInfo:r,syncStatus:o,changeSummary:n,recentChanges:l}=ze(),h=O(c==null?void 0:c.uptime);if(i==="disconnected")return t.jsx("div",{className:s.page,children: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 m=(r==null?void 0:r.mcpInstanceCount)??0,d=((I=r==null?void 0:r.mcpInstances)==null?void 0:I.find(b=>!b.isServer&&b.aiClientName))??((C=r==null?void 0:r.mcpInstances)==null?void 0:C.find(b=>!!b.aiClientName))??null,w=(c==null?void 0:c.pluginClients)??[],N=w.length>0,S=(c==null?void 0:c.sessionId)??(r==null?void 0:r.sessionId)??"-",_=e("overview.metric.server.tooltip","MCP server runtime and process status"),y=e("overview.metric.plugin.tooltip","Roblox Studio plugin connection and version status"),a=e("overview.metric.agent.tooltip","Connected AI coding agents and their runtime state"),f=e("overview.metric.sync.tooltip","Current Studio to local sync activity"),x=c?[k(s,e("overview.meta.version","Version"),e("overview.meta.version.tooltip","Installed MCP server version"),`v${c.version}`),k(s,e("overview.meta.session","Session"),e("overview.meta.session.tooltip","Current MCP session identifier"),S),k(s,e("overview.meta.pid","PID"),e("overview.meta.pid.tooltip","Operating system process identifier"),String(c.pid??"-")),k(s,e("overview.meta.uptime","Uptime"),e("overview.meta.uptime.tooltip","Time elapsed since the MCP server started"),X(h??c.uptime))]:[];if(i==="serverOnly")return t.jsxs("div",{className:s.page,children:[t.jsxs("div",{className:s.metricRow,children:[t.jsx(j,{title:g(e("overview.metric.server"),_),value:g(e("status.online"),_),icon:"🖥️",status:"ok",children:t.jsxs(t.Fragment,{children:[x,t.jsx(A,{status:"online"})]})}),t.jsx(j,{title:g(e("overview.metric.agent"),a),value:g((d==null?void 0:d.aiClientName)??e("overview.metric.noAgent"),a),icon:"🤖",subtitle:m>1?`${m} ${e("overview.metric.agent.instancesUnit","instances")}`:void 0,status:d?"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(B,{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 p=w[0],u=n?D(n):0,T=!!n&&u>0;return t.jsxs("div",{className:s.page,children:[t.jsxs("div",{className:s.metricGrid,children:[t.jsx(j,{title:g(e("overview.metric.server"),_),value:g(e("status.online"),_),icon:"🖥️",status:"ok",children:t.jsx(t.Fragment,{children:x})}),t.jsx(j,{title:g(e("overview.metric.plugin"),y),value:g(e(N?"status.online":"status.offline"),y),icon:"🔌",subtitle:p?`${p.placeName??p.projectName??"-"} / v${p.pluginVersion??"-"}`:void 0,status:N?"ok":"error"}),t.jsx(j,{title:g(e("overview.metric.agent"),a),value:g((d==null?void 0:d.aiClientName)??e("overview.metric.noAgent"),a),icon:"🤖",subtitle:m>1?`${m} ${e("overview.metric.agent.instancesUnit","instances")}`:void 0,status:d?"ok":"warn"}),t.jsx(j,{title:g(e("overview.metric.sync"),f),value:g(Oe(o==null?void 0:o.state,e),f),icon:"🔄",status:Xe(o==null?void 0:o.state)})]}),t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.feed.title")}),t.jsx(B,{changes:l})]}),T&&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"),": ",u]}),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{Ze as Component};
@@ -1,4 +1,4 @@
1
- import{r as n,a as f,u as b,j as e,i as A,l as H,m as D,p as E}from"./index-BPIBy2lU.js";import{D as U,T as $}from"./TierComparison-poRtDe46.js";import{I}from"./InfoLabel-B_fEbHa7.js";import{T as _}from"./TooltipText-DX5jnyNF.js";import{C as O}from"./ConfirmModal-Cpk7SbKb.js";const F=5e3;function W(t){const r=(t==null?void 0:t.enabled)??!0,[p,o]=n.useState([]),[a,l]=n.useState(null),[d,i]=n.useState(r),c=n.useRef(null),h=n.useCallback(async()=>{try{const x=await f.get("/api/dashboard/playtest/history");o(x.entries??[])}catch{}},[]),m=n.useCallback(async()=>{if(!r){i(!1);return}await h(),i(!1)},[r,h]),y=n.useCallback(async()=>{r&&(await f.post("/api/dashboard/playtest/history/clear"),o([]),l(null))},[r]),g=n.useCallback(async x=>{if(r)try{const v=await f.get(`/api/dashboard/playtest/report/${x}`);l(v)}catch{l(null)}},[r]);return n.useEffect(()=>{if(!r){i(!1);return}return m(),c.current=setInterval(m,F),()=>{c.current&&clearInterval(c.current)}},[r,m]),{history:p,selectedReport:a,loading:d,loadReport:g,clearHistory:y}}function V(t){const r="2026-03-27T15:26:00.000Z",p={testScenario:t("playtest.sample.context.why","Spawn into the arena, survive the opener, and verify the HUD responds immediately."),expectedBehavior:t("playtest.sample.context.expected","The player spawns safely, the countdown UI appears within one second, and the first wave starts without errors."),observedBehavior:t("playtest.sample.context.observed","Spawn protection held, the HUD updated on time, and wave one completed with no gameplay regressions.")};return{history:[{timestamp:r,testName:t("playtest.sample.history.name","Sample Arena Smoke Test"),mode:"play",status:"passed",durationMs:4820,contextId:"sample_playtest_preview",contextSummary:p}],report:{markdown:t("playtest.sample.report.markdown",`# Sample Arena Smoke Test
1
+ import{r as n,a as f,u as b,j as e,i as A,l as H,m as D,p as E}from"./index-C9gmLH8z.js";import{D as U,T as $}from"./TierComparison-Lkag7n54.js";import{I}from"./InfoLabel-Bp3j_i44.js";import{T as _}from"./TooltipText-Bgk-NYKr.js";import{C as O}from"./ConfirmModal-Dg8_uxRE.js";const F=5e3;function W(t){const r=(t==null?void 0:t.enabled)??!0,[p,o]=n.useState([]),[a,l]=n.useState(null),[d,i]=n.useState(r),c=n.useRef(null),h=n.useCallback(async()=>{try{const x=await f.get("/api/dashboard/playtest/history");o(x.entries??[])}catch{}},[]),m=n.useCallback(async()=>{if(!r){i(!1);return}await h(),i(!1)},[r,h]),y=n.useCallback(async()=>{r&&(await f.post("/api/dashboard/playtest/history/clear"),o([]),l(null))},[r]),g=n.useCallback(async x=>{if(r)try{const v=await f.get(`/api/dashboard/playtest/report/${x}`);l(v)}catch{l(null)}},[r]);return n.useEffect(()=>{if(!r){i(!1);return}return m(),c.current=setInterval(m,F),()=>{c.current&&clearInterval(c.current)}},[r,m]),{history:p,selectedReport:a,loading:d,loadReport:g,clearHistory:y}}function V(t){const r="2026-03-27T15:26:00.000Z",p={testScenario:t("playtest.sample.context.why","Spawn into the arena, survive the opener, and verify the HUD responds immediately."),expectedBehavior:t("playtest.sample.context.expected","The player spawns safely, the countdown UI appears within one second, and the first wave starts without errors."),observedBehavior:t("playtest.sample.context.observed","Spawn protection held, the HUD updated on time, and wave one completed with no gameplay regressions.")};return{history:[{timestamp:r,testName:t("playtest.sample.history.name","Sample Arena Smoke Test"),mode:"play",status:"passed",durationMs:4820,contextId:"sample_playtest_preview",contextSummary:p}],report:{markdown:t("playtest.sample.report.markdown",`# Sample Arena Smoke Test
2
2
 
3
3
  - Spawn flow: PASS
4
4
  - HUD countdown: PASS