@weppy/roblox-mcp 2.7.0 → 2.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +14 -17
- package/install.sh +3 -4
- package/package.json +1 -1
- package/plugins/weppy-roblox-mcp/.claude-plugin/plugin.json +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ChangelogDetailPage-CIarzJIx.js → ChangelogDetailPage-DxktONbL.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ChangelogPage-C1uCKyqh.js → ChangelogPage-DOY-SmWM.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ConfirmModal-BDWSInRi.js → ConfirmModal-CmJCz5rg.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ConnectionPage-CWDwVCKg.js → ConnectionPage-BiiIQs7f.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{GameChangeDetail-Bk8YUy4G.js → GameChangeDetail-D1kE2L_v.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{InfoLabel-BJIFNYA5.js → InfoLabel-B9KT3kfU.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{OverviewPage-Di0p7YY2.js → OverviewPage-T2WCTHpo.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{PlaytestPage-Dxgz0SKW.js → PlaytestPage-CW8Xfp6b.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{SettingsPage-DVgxRsfC.js → SettingsPage-DcUt5qjG.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{StatusBadge-ilvVufN2.js → StatusBadge-Bxe88ki2.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{SyncPage-IICMnq8v.js → SyncPage-C09YF6D5.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{Tabs-pDS5zzr9.js → Tabs-BNtOqYlc.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierComparison-Dyf-knpe.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ToolsPage-DEhsoa36.js → ToolsPage-HKbmsKMQ.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{TooltipText-bSKcc3-P.js → TooltipText-Baw38jOU.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{UiStudioPage-BHhd3zUv.js → UiStudioPage-Cbgl7xIC.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{WhatsNewPage-ErpENbsZ.js → WhatsNewPage-BlOSWgSn.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{index-BPAvjNNu.js → index-FfT2oWAB.js} +28 -28
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{sample-requests-DDQ3XchF.js → sample-requests-X_hsWdLX.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{useLiveUptime-HYmdQdHf.js → useLiveUptime-DhJz484L.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/index.html +1 -1
- package/plugins/weppy-roblox-mcp/dist/index.js +4 -4
- package/plugins/weppy-roblox-mcp/roblox-plugin/WeppyRobloxMCP.rbxm +0 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierComparison-BXMCd1IB.js +0 -2
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Weppy Roblox MCP — MCP server that lets AI coding agents control a live Roblox Studio session with 21 tools, 140+ actions, bidirectional sync, automated playtest, and multi-place support",
|
|
9
|
-
"version": "2.7.
|
|
9
|
+
"version": "2.7.1"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "weppy-roblox-mcp",
|
|
14
14
|
"source": "./plugins/weppy-roblox-mcp",
|
|
15
15
|
"description": "Weppy Roblox MCP — MCP server that lets AI coding agents control a live Roblox Studio session with 21 tools, 140+ actions, bidirectional sync, automated playtest, and multi-place support",
|
|
16
|
-
"version": "2.7.
|
|
16
|
+
"version": "2.7.1",
|
|
17
17
|
"author": {
|
|
18
18
|
"name": "hope1026"
|
|
19
19
|
},
|
package/CHANGELOG.md
CHANGED
|
@@ -3,33 +3,30 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
## [2.7.
|
|
7
|
-
|
|
8
|
-
### Features
|
|
6
|
+
## [2.7.1] - 2026-05-05
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
- **UI Studio retention & storage controls** — A new **Storage** card on the dashboard lets you set a retention policy (max age + max size) for UI Studio request history. The retention runner cleans old runs in the background and supports dry-run preview before deletion. History entries can also be batch-selected and deleted from the Analysis tab.
|
|
13
|
-
|
|
14
|
-
- **UI Studio dashboard redesign** — The UI Studio page is now split into **History** and **Analysis** tabs with a redesigned snapshot drawer (persistent toolbar, focus trap, drawer/dialog comparison view), tooltip help across UI Studio + Settings, a new connection guide for first-time users, and localized analysis detail strings. Thumbnails now use `object-fit: contain` so layouts aren't cropped.
|
|
8
|
+
### Improvements
|
|
15
9
|
|
|
16
|
-
- **
|
|
10
|
+
- **Stability hardening** — Internal reliability improvements across the MCP server and Roblox Studio plugin. No behavior changes for existing workflows.
|
|
17
11
|
|
|
18
|
-
|
|
12
|
+
## [2.7.0] - 2026-05-05
|
|
19
13
|
|
|
20
|
-
###
|
|
14
|
+
### Features
|
|
21
15
|
|
|
22
|
-
- **
|
|
16
|
+
- **UI Studio launch** — A new workflow for iterating on Roblox Studio UI design together with an AI agent. From the UI Studio page in the dashboard, you can now use:
|
|
17
|
+
- **History tab** — Compare before/after snapshots and design suggestions for each request, side by side.
|
|
18
|
+
- **Analysis tab** — Snapshot comparison modal with batch selection and deletion.
|
|
19
|
+
- **Design Check** — Reviews your UI against design quality criteria and surfaces concrete improvements.
|
|
23
20
|
|
|
24
|
-
|
|
21
|
+
### Improvements
|
|
25
22
|
|
|
26
|
-
- **
|
|
23
|
+
- **More accurate property types when syncing local edits back to Studio** — When you edit synced files locally and push the changes back to Studio, the server now resolves property types via class-aware metadata instead of guessing from value shape. Edits to enum, color, or vector properties on specific instances are no longer silently saved as the wrong type.
|
|
27
24
|
|
|
28
|
-
###
|
|
25
|
+
### Bug Fixes
|
|
29
26
|
|
|
30
|
-
- **
|
|
27
|
+
- **Claude Code detection on Windows** — On Windows, Claude Code could be mis-detected and even a fresh install would fail with a confusing "already exists" error. Detection is now correct, and an existing valid registration is treated as success.
|
|
31
28
|
|
|
32
|
-
- **
|
|
29
|
+
- **Dashboard tooltips no longer clipped** — Tooltips inside scrollable areas (Settings, UI Studio history) were being cut off. They now display in full regardless of the surrounding container.
|
|
33
30
|
|
|
34
31
|
|
|
35
32
|
|
package/install.sh
CHANGED
|
@@ -120,8 +120,7 @@ try {
|
|
|
120
120
|
' >/dev/null 2>&1
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
#
|
|
124
|
-
# config and strip any legacy flat key left over from earlier versions.
|
|
123
|
+
# Antigravity 설정에 canonical mcpServers 래퍼로 MCP 서버를 추가하고 legacy flat key를 정리
|
|
125
124
|
add_antigravity_mcp_config() {
|
|
126
125
|
local config_path="$1"
|
|
127
126
|
local parent_dir
|
|
@@ -657,8 +656,8 @@ if confirm " Run npx -y @weppy/roblox-mcp@latest --setup?"; then
|
|
|
657
656
|
fi
|
|
658
657
|
|
|
659
658
|
if [ -n "${setup_tmp_dir:-}" ] && [ -d "$setup_tmp_dir" ]; then
|
|
660
|
-
#
|
|
661
|
-
#
|
|
659
|
+
# stdin을 /dev/null로 격리: curl|bash 파이프 모드에서 stdio MCP 서버가
|
|
660
|
+
# bash의 남은 스크립트 바이트를 소비해버리는 문제를 방지한다
|
|
662
661
|
# The @latest tag forces npx to resolve from the registry instead of
|
|
663
662
|
# reusing an older version pinned in the npm cache.
|
|
664
663
|
if (cd "$setup_tmp_dir" && npx -y "@weppy/roblox-mcp@latest" --setup </dev/null); then
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weppy/roblox-mcp",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.1",
|
|
4
4
|
"description": "MCP (Model Context Protocol) server for Roblox Studio integration - enables AI coding agents to interact with Roblox Studio in real-time",
|
|
5
5
|
"main": "plugins/weppy-roblox-mcp/dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r,a as R,u as M,b as B,c as V,j as e}from"./index-BPAvjNNu.js";import{I as G}from"./InfoLabel-BJIFNYA5.js";import{G as D}from"./GameChangeDetail-Bk8YUy4G.js";import{T as m}from"./TooltipText-bSKcc3-P.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-FfT2oWAB.js";import{I as G}from"./InfoLabel-B9KT3kfU.js";import{G as D}from"./GameChangeDetail-D1kE2L_v.js";import{T as m}from"./TooltipText-Baw38jOU.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 i,a as A,D as O,u as R,j as t,c as P,l as V,m as K}from"./index-
|
|
1
|
+
import{r as i,a as A,D as O,u as R,j as t,c as P,l as V,m as K}from"./index-FfT2oWAB.js";import{C as G}from"./ConfirmModal-CmJCz5rg.js";import{T as I}from"./TooltipText-Baw38jOU.js";import{T as H}from"./Tabs-BNtOqYlc.js";const U=10;function Z(){const[s,m]=i.useState([]),[e,a]=i.useState(0),[h,p]=i.useState(!1),[c,f]=i.useState(!0),[l,x]=i.useState(0),[g,v]=i.useState("all"),y=i.useRef(null),o=i.useCallback(async(u,_)=>{f(!0);try{const C={limit:String(U),offset:String(u)};_!=="all"&&(C.status=_);const b=await A.get("/api/dashboard/changelog",C);m(b.entries),a(b.total),p(b.hasMore)}catch{m([]),a(0),p(!1)}finally{f(!1)}},[]),T=i.useCallback(()=>{o(l,g)},[o,l,g]),N=i.useCallback(async()=>{await A.post("/api/dashboard/changelog/clear"),m([]),a(0),p(!1)},[]);return i.useEffect(()=>{o(l,g)},[o,l,g]),i.useEffect(()=>{const u=new O;y.current=u,u.connect();const _=u.on("command",()=>{o(l,g)});return()=>{_(),u.disconnect(),y.current=null}},[o,l,g]),{entries:s,total:e,hasMore:h,loading:c,offset:l,statusFilter:g,setOffset:x,setStatusFilter:v,refresh:T,clear:N}}const q="_card_1n89u_2",z="_header_1n89u_17",J="_statusBadge_1n89u_24",Q="_statusDot_1n89u_35",W="_active_1n89u_41",X="_completed_1n89u_50",Y="_timeRange_1n89u_58",ee="_summaryList_1n89u_65",te="_summaryItem_1n89u_71",se="_summaryIcon_1n89u_80",ae="_summaryText_1n89u_86",ne="_progressBar_1n89u_91",oe="_progressFill_1n89u_99",ce="_emptySummary_1n89u_112",ie="_contextBlock_1n89u_120",le="_contextLabel_1n89u_129",re="_contextValue_1n89u_137",n={card:q,header:z,statusBadge:J,statusDot:Q,active:W,completed:X,timeRange:Y,summaryList:ee,summaryItem:te,summaryIcon:se,summaryText:ae,progressBar:ne,progressFill:oe,emptySummary:ce,contextBlock:ie,contextLabel:le,contextValue:re};function D(s){if(!s)return"--:--";const m=new Date(s);return`${String(m.getHours()).padStart(2,"0")}:${String(m.getMinutes()).padStart(2,"0")}`}function de({entry:s,onClick:m}){var C,b,$,w,B,k,L,M,E,F;const{t:e}=R(),a=s.changeSummary,h=s.status==="active",p=s.isBootstrapOnly===!0,c=[],f=a.scriptsModified+a.scriptsCreated;if(f>0){const r=[];a.scriptsModified>0&&r.push(`${a.scriptsModified} ${e("changelog.card.modified","modified")}`),a.scriptsCreated>0&&r.push(`${a.scriptsCreated} ${e("changelog.card.created","created")}`);const j=`${f} ${e("changelog.card.scripts","scripts")} ${r.join(", ")}`;c.push({icon:"📝",text:j,tooltip:e("changelog.card.scripts.tooltip","Script changes made in this session.")})}const l=a.instancesCreated+a.instancesDeleted+a.instancesMoved;if(l>0){const r=[];a.instancesCreated>0&&r.push(`${a.instancesCreated} ${e("changelog.card.created","created")}`),a.instancesDeleted>0&&r.push(`${a.instancesDeleted} ${e("changelog.card.deleted","deleted")}`),a.instancesMoved>0&&r.push(`${a.instancesMoved} ${e("changelog.card.moved","moved")}`);const j=`${l} ${e("changelog.card.instances","instances")} ${r.join(", ")}`;c.push({icon:"🧱",text:j,tooltip:e("changelog.card.instances.tooltip","Instance create, delete, move, or clone changes in this session.")})}a.propertiesChanged>0&&c.push({icon:"🎨",text:`${a.propertiesChanged} ${e("changelog.card.propertiesChanged","properties changed")}`,tooltip:e("changelog.card.propertiesChanged.tooltip","Property value changes recorded for this session.")}),a.lightingChanged&&c.push({icon:"🌅",text:e("changelog.card.lightingConfigured","Lighting configured"),tooltip:e("changelog.card.lightingConfigured.tooltip","Lighting or atmosphere settings changed in this session.")}),a.terrainChanged&&c.push({icon:"⛰️",text:e("changelog.card.terrainConfigured","Terrain configured"),tooltip:e("changelog.card.terrainConfigured.tooltip","Terrain data or terrain settings changed in this session.")}),a.assetsInserted>0&&c.push({icon:"📦",text:`${a.assetsInserted} ${e("changelog.card.assetsInserted","assets inserted")}`,tooltip:e("changelog.card.assetsInserted.tooltip","Assets inserted into the place during this session.")});const x=D(s.startTime),g=h?e("changelog.card.inProgress","in progress"):s.endTime?D(s.endTime):"--:--",v=p?e("changelog.card.bootstrapStatus","Bootstrap"):h?e("changelog.card.active","Active"):e("changelog.card.completed","Completed"),y=p?e("changelog.card.bootstrapStatus.tooltip","This session only contains the initial sync bootstrap snapshot."):h?e("changelog.card.active.tooltip","This session is still receiving new game changes."):e("changelog.card.completed.tooltip","This session has ended and no more changes are expected."),o=p?e("changelog.card.bootstrapSummary","Initial sync snapshot"):e("changelog.card.noChanges","No changes yet"),T=p?e("changelog.card.bootstrapSummary.tooltip","Initial file sync writes are collapsed into a single bootstrap snapshot row."):e("changelog.card.noChanges.tooltip","No game changes have been extracted for this session yet."),N=(b=(C=s.contextSummary)==null?void 0:C.intent)==null?void 0:b.trim(),u=((k=(B=(w=($=s.contextSummary)==null?void 0:$.affectedAreas)==null?void 0:w[0])==null?void 0:B.label)==null?void 0:k.trim())||((M=(L=s.contextSummary)==null?void 0:L.testScenario)==null?void 0:M.trim()),_=(F=(E=s.verificationSummary)==null?void 0:E.label)==null?void 0:F.trim();return t.jsxs("div",{className:n.card,onClick:m,children:[t.jsxs("div",{className:n.header,children:[t.jsx(I,{text:y,children:t.jsxs("span",{className:`${n.statusBadge} ${h?n.active:n.completed}`,children:[t.jsx("span",{className:n.statusDot}),v]})}),t.jsxs("span",{className:n.timeRange,children:[x,"~",g]})]}),t.jsx("div",{className:n.summaryList,children:c.length>0?c.map((r,j)=>t.jsxs("div",{className:n.summaryItem,children:[t.jsx("span",{className:n.summaryIcon,children:r.icon}),t.jsx(I,{text:r.tooltip,children:t.jsx("span",{className:n.summaryText,children:r.text})})]},j)):t.jsx(I,{text:T,children:t.jsx("span",{className:n.emptySummary,style:{display:"block"},children:o})})}),N&&t.jsxs("div",{className:n.contextBlock,children:[t.jsx("span",{className:n.contextLabel,children:e("changelog.card.sessionIntent","Session intent")}),t.jsx("span",{className:n.contextValue,children:N})]}),!N&&u&&t.jsxs("div",{className:n.contextBlock,children:[t.jsx("span",{className:n.contextLabel,children:e("changelog.card.representativeArea","Representative area")}),t.jsx("span",{className:n.contextValue,children:u})]}),_&&t.jsxs("div",{className:n.contextBlock,children:[t.jsx("span",{className:n.contextLabel,children:e("changelog.card.verification","Verification")}),t.jsx("span",{className:n.contextValue,children:_})]}),h&&t.jsx("div",{className:n.progressBar,children:t.jsx("div",{className:n.progressFill})})]})}const ge="_page_1ynbw_2",me="_limitNotice_1ynbw_9",he="_limitNoticeTitle_1ynbw_18",pe="_limitNoticeText_1ynbw_25",ue="_clearButton_1ynbw_33",fe="_list_1ynbw_54",xe="_empty_1ynbw_61",_e="_loading_1ynbw_70",ye="_pagination_1ynbw_79",be="_pageInfo_1ynbw_87",ve="_btn_1ynbw_93",d={page:ge,limitNotice:me,limitNoticeTitle:he,limitNoticeText:pe,clearButton:ue,list:fe,empty:xe,loading:_e,pagination:ye,pageInfo:be,btn:ve},S=10,Ne=[{key:"all",labelKey:"changelog.filter.all"},{key:"active",labelKey:"changelog.filter.active"},{key:"completed",labelKey:"changelog.filter.completed"}];function Ie(){const{t:s}=R(),m=P(),e=Z(),a=V(),{show:h}=K(),[p,c]=i.useState(!1),[f,l]=i.useState(!1),x=!a.loading&&a.tier==="basic",g=x?e.entries.slice(0,3):e.entries,v=!x&&e.total>S,y=async()=>{l(!0);try{await e.clear(),h(s("toast.clearSuccess","Cleared successfully"),"success"),c(!1)}catch{h(s("toast.clearFailed","Failed to clear data"),"error")}finally{l(!1)}};return t.jsxs("div",{className:d.page,children:[t.jsx(H,{items:Ne.map(o=>({key:o.key,label:s(o.labelKey,o.key.charAt(0).toUpperCase()+o.key.slice(1))})),value:e.statusFilter,onChange:o=>{e.setStatusFilter(o),e.setOffset(0)},rightActions:t.jsx("button",{className:d.clearButton,onClick:()=>c(!0),children:s("common.clear","Clear")})}),e.loading&&e.entries.length===0&&t.jsx("div",{className:d.loading,children:s("common.loading","Loading...")}),!e.loading&&e.entries.length===0?t.jsx("div",{className:d.empty,children:s("changelog.empty","No changelog entries yet")}):t.jsx("div",{className:d.list,children:g.map(o=>t.jsx(de,{entry:o,onClick:()=>m(`/changelog/${o.entryId}`)},o.entryId))}),v&&t.jsxs("div",{className:d.pagination,children:[t.jsx("button",{className:d.btn,disabled:e.offset===0,onClick:()=>e.setOffset(Math.max(0,e.offset-S)),children:s("tools.page.prev","Prev")}),t.jsxs("span",{className:d.pageInfo,children:[e.offset+1,"–",Math.min(e.offset+S,e.total)," / ",e.total]}),t.jsx("button",{className:d.btn,disabled:!e.hasMore,onClick:()=>e.setOffset(e.offset+S),children:s("tools.page.next","Next")})]}),x&&t.jsx(t.Fragment,{children:t.jsxs("div",{className:d.limitNotice,children:[t.jsx("div",{className:d.limitNoticeTitle,children:s("changelog.basic.limit.title","Basic preview shows the latest 3 sessions")}),t.jsx("div",{className:d.limitNoticeText,children:s("changelog.basic.limit.body","Upgrade to Pro to browse the full changelog timeline for this place.")})]})}),t.jsx(G,{open:p,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:f,onCancel:()=>!f&&c(!1),onConfirm:y})]})}export{Ie as Component};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as s,w as e}from"./index-
|
|
1
|
+
import{j as s,w as e}from"./index-FfT2oWAB.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 i,j as e,d as E,a as w,D as B,m as P}from"./index-BPAvjNNu.js";import{I as r}from"./InfoLabel-BJIFNYA5.js";import{S as T}from"./StatusBadge-ilvVufN2.js";import{T as D}from"./TooltipText-bSKcc3-P.js";import{C as $}from"./ConfirmModal-BDWSInRi.js";import{u as F,f as H}from"./useLiveUptime-HYmdQdHf.js";const U="_container_1h084_2",K="_entry_1h084_14",G="_timestamp_1h084_21",O="_message_1h084_27",V="_warn_1h084_34",X="_error_1h084_39",z="_empty_1h084_44",_={container:U,entry:K,timestamp:G,message:O,warn:V,error:X,empty:z};function J(n){const t=new Date(n);return Number.isNaN(t.getTime())?n:`${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`}function Q({entries:n}){const{t}=R(),o=i.useRef(null);return i.useEffect(()=>{const l=o.current;l&&(l.scrollTop=l.scrollHeight)},[n.length]),e.jsx("div",{ref:o,className:_.container,children:n.length===0?e.jsx("div",{className:_.empty,children:t("connection.log.empty","No events yet")}):n.map((l,j)=>e.jsxs("div",{className:`${_.entry} ${l.type?_[l.type]:""}`,children:[e.jsx("span",{className:_.timestamp,children:J(l.timestamp)}),e.jsx("span",{className:_.message,children:l.message})]},j))})}const A=50;function W(){const n=new Date;return`${String(n.getHours()).padStart(2,"0")}:${String(n.getMinutes()).padStart(2,"0")}`}function Y(){const{level:n,status:t,error:o}=E(),[l,j]=i.useState(null),[k,f]=i.useState([]),g=i.useRef(null),u=i.useCallback((a,d)=>{f(x=>{const m=[...x,{timestamp:W(),message:a,type:d}];return m.length>A?m.slice(-A):m})},[]),h=i.useCallback(async()=>{try{const a=await w.get("/connection-info");j(a)}catch{j(null)}},[]),y=i.useCallback(async()=>{try{const a=await w.get("/api/dashboard/connection-log");f(a.entries??[])}catch{f([])}},[]),v=i.useCallback(async()=>{await w.post("/api/dashboard/connection-log/clear"),f([])},[]),S=i.useCallback(async a=>{await w.post("/api/dashboard/kill-agent",{instanceId:a}),await h()},[h]);return i.useEffect(()=>{n!=="disconnected"&&t&&h(),y()},[n,t,h,y]),i.useEffect(()=>{const a=new B;g.current=a,a.connect();const d=a.on("connection",m=>{const p=m,b=p.status==="connected"?"connected":"disconnected";u(`Plugin ${b} — ${p.clientId}`,p.status==="connected"?"info":"warn")}),x=a.on("mcp_status",m=>{const p=m,b=p.status==="registered"?"registered":"unregistered";u(`MCP ${b} — ${p.aiClientName}`,p.status==="registered"?"info":"warn"),h()});return()=>{d(),x(),a.disconnect(),g.current=null}},[u,h]),{status:t,connectionInfo:l,connectionLog:k,level:n,error:o,clearConnectionLog:v,killAgent:S}}const Z="_page_sf4qa_2",ee="_card_sf4qa_10",ne="_disabled_sf4qa_18",te="_cardHeader_sf4qa_24",se="_clearButton_sf4qa_37",ce="_serverGrid_sf4qa_47",oe="_statusRow_sf4qa_65",ie="_metaItem_sf4qa_72",ae="_table_sf4qa_79",le="_toggleBtn_sf4qa_104",re="_disconnected_sf4qa_119",de="_disconnectedActions_sf4qa_136",me="_btn_sf4qa_143",pe="_activity_active_sf4qa_161",he="_activity_stale_sf4qa_162",ge="_activity_unknown_sf4qa_163",ue="_killBtn_sf4qa_187",xe="_emptyRow_sf4qa_207",s={page:Z,card:ee,disabled:ne,cardHeader:te,clearButton:se,serverGrid:ce,statusRow:oe,metaItem:ie,table:ae,toggleBtn:le,disconnected:re,disconnectedActions:de,btn:me,activity_active:pe,activity_stale:he,activity_unknown:ge,killBtn:ue,emptyRow:xe};function N(n,t){const o=Math.max(0,Math.floor((Date.now()-n)/1e3));return o<60?`${o}${t("connection.time.secondsAgo","s ago")}`:o<3600?`${Math.floor(o/60)}${t("connection.time.minutesAgo","m ago")}`:`${Math.floor(o/3600)}${t("connection.time.hoursAgo","h ago")}`}function je(n){return n?Date.now()-n<3e4?"active":"stale":"unknown"}function Se(){var I;const{t:n}=R(),{status:t,connectionInfo:o,connectionLog:l,level:j,clearConnectionLog:k,killAgent:f}=Y(),{show:g}=P(),[u,h]=i.useState(!0),[y,v]=i.useState(!1),[S,a]=i.useState(!1),[d,x]=i.useState(null),[m,p]=i.useState(!1),b=F(t==null?void 0:t.uptime),C=j==="disconnected",L=C?"offline":"online",q=async()=>{if(d){p(!0);try{await f(d.instanceId),g(n("connection.agents.killed","Agent killed"),"success"),x(null)}catch{g(n("connection.agents.killFailed","Failed to kill agent"),"error")}finally{p(!1)}}},M=async()=>{a(!0);try{await k(),g(n("toast.clearSuccess","Cleared successfully"),"success"),v(!1)}catch{g(n("toast.clearFailed","Failed to clear data"),"error")}finally{a(!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")}),C?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(T,{status:L})}),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(D,{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:H(b??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} ${C?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:()=>h(c=>!c),"aria-label":u?n("common.collapse","Collapse"):n("common.expand","Expand"),children:u?"▾":"▸"})]}),u&&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_${je(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:N(c.connectedAt,n)}),e.jsx("td",{children:c.lastSeen?N(c.lastSeen,n):"-"}),e.jsx("td",{children:c.lastCommandAt?N(c.lastCommandAt,n):"-"}),e.jsx("td",{children:!c.isServer&&e.jsx("button",{className:s.killBtn,onClick:()=>x({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} ${C?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:N(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} ${C?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:()=>v(!0),children:n("common.clear","Clear")})]}),e.jsx(Q,{entries:l})]}),e.jsx($,{open:y,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:S,onCancel:()=>!S&&v(!1),onConfirm:M}),e.jsx($,{open:!!d,title:n("connection.agents.kill.title","Kill agent?"),message:`"${d==null?void 0:d.name}" 프로세스를 강제 종료합니다. 해당 에이전트의 진행 중인 작업이 중단됩니다.`,cancelLabel:n("common.cancel","Cancel"),confirmLabel:n("connection.agents.kill","Kill"),loading:m,onCancel:()=>!m&&x(null),onConfirm:q})]})}export{Se as Component};
|
|
1
|
+
import{u as R,r as i,j as e,d as E,a as w,D as B,m as P}from"./index-FfT2oWAB.js";import{I as r}from"./InfoLabel-B9KT3kfU.js";import{S as T}from"./StatusBadge-Bxe88ki2.js";import{T as D}from"./TooltipText-Baw38jOU.js";import{C as $}from"./ConfirmModal-CmJCz5rg.js";import{u as F,f as H}from"./useLiveUptime-DhJz484L.js";const U="_container_1h084_2",K="_entry_1h084_14",G="_timestamp_1h084_21",O="_message_1h084_27",V="_warn_1h084_34",X="_error_1h084_39",z="_empty_1h084_44",_={container:U,entry:K,timestamp:G,message:O,warn:V,error:X,empty:z};function J(n){const t=new Date(n);return Number.isNaN(t.getTime())?n:`${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`}function Q({entries:n}){const{t}=R(),o=i.useRef(null);return i.useEffect(()=>{const l=o.current;l&&(l.scrollTop=l.scrollHeight)},[n.length]),e.jsx("div",{ref:o,className:_.container,children:n.length===0?e.jsx("div",{className:_.empty,children:t("connection.log.empty","No events yet")}):n.map((l,j)=>e.jsxs("div",{className:`${_.entry} ${l.type?_[l.type]:""}`,children:[e.jsx("span",{className:_.timestamp,children:J(l.timestamp)}),e.jsx("span",{className:_.message,children:l.message})]},j))})}const A=50;function W(){const n=new Date;return`${String(n.getHours()).padStart(2,"0")}:${String(n.getMinutes()).padStart(2,"0")}`}function Y(){const{level:n,status:t,error:o}=E(),[l,j]=i.useState(null),[k,f]=i.useState([]),g=i.useRef(null),u=i.useCallback((a,d)=>{f(x=>{const m=[...x,{timestamp:W(),message:a,type:d}];return m.length>A?m.slice(-A):m})},[]),h=i.useCallback(async()=>{try{const a=await w.get("/connection-info");j(a)}catch{j(null)}},[]),y=i.useCallback(async()=>{try{const a=await w.get("/api/dashboard/connection-log");f(a.entries??[])}catch{f([])}},[]),v=i.useCallback(async()=>{await w.post("/api/dashboard/connection-log/clear"),f([])},[]),S=i.useCallback(async a=>{await w.post("/api/dashboard/kill-agent",{instanceId:a}),await h()},[h]);return i.useEffect(()=>{n!=="disconnected"&&t&&h(),y()},[n,t,h,y]),i.useEffect(()=>{const a=new B;g.current=a,a.connect();const d=a.on("connection",m=>{const p=m,b=p.status==="connected"?"connected":"disconnected";u(`Plugin ${b} — ${p.clientId}`,p.status==="connected"?"info":"warn")}),x=a.on("mcp_status",m=>{const p=m,b=p.status==="registered"?"registered":"unregistered";u(`MCP ${b} — ${p.aiClientName}`,p.status==="registered"?"info":"warn"),h()});return()=>{d(),x(),a.disconnect(),g.current=null}},[u,h]),{status:t,connectionInfo:l,connectionLog:k,level:n,error:o,clearConnectionLog:v,killAgent:S}}const Z="_page_sf4qa_2",ee="_card_sf4qa_10",ne="_disabled_sf4qa_18",te="_cardHeader_sf4qa_24",se="_clearButton_sf4qa_37",ce="_serverGrid_sf4qa_47",oe="_statusRow_sf4qa_65",ie="_metaItem_sf4qa_72",ae="_table_sf4qa_79",le="_toggleBtn_sf4qa_104",re="_disconnected_sf4qa_119",de="_disconnectedActions_sf4qa_136",me="_btn_sf4qa_143",pe="_activity_active_sf4qa_161",he="_activity_stale_sf4qa_162",ge="_activity_unknown_sf4qa_163",ue="_killBtn_sf4qa_187",xe="_emptyRow_sf4qa_207",s={page:Z,card:ee,disabled:ne,cardHeader:te,clearButton:se,serverGrid:ce,statusRow:oe,metaItem:ie,table:ae,toggleBtn:le,disconnected:re,disconnectedActions:de,btn:me,activity_active:pe,activity_stale:he,activity_unknown:ge,killBtn:ue,emptyRow:xe};function N(n,t){const o=Math.max(0,Math.floor((Date.now()-n)/1e3));return o<60?`${o}${t("connection.time.secondsAgo","s ago")}`:o<3600?`${Math.floor(o/60)}${t("connection.time.minutesAgo","m ago")}`:`${Math.floor(o/3600)}${t("connection.time.hoursAgo","h ago")}`}function je(n){return n?Date.now()-n<3e4?"active":"stale":"unknown"}function Se(){var I;const{t:n}=R(),{status:t,connectionInfo:o,connectionLog:l,level:j,clearConnectionLog:k,killAgent:f}=Y(),{show:g}=P(),[u,h]=i.useState(!0),[y,v]=i.useState(!1),[S,a]=i.useState(!1),[d,x]=i.useState(null),[m,p]=i.useState(!1),b=F(t==null?void 0:t.uptime),C=j==="disconnected",L=C?"offline":"online",q=async()=>{if(d){p(!0);try{await f(d.instanceId),g(n("connection.agents.killed","Agent killed"),"success"),x(null)}catch{g(n("connection.agents.killFailed","Failed to kill agent"),"error")}finally{p(!1)}}},M=async()=>{a(!0);try{await k(),g(n("toast.clearSuccess","Cleared successfully"),"success"),v(!1)}catch{g(n("toast.clearFailed","Failed to clear data"),"error")}finally{a(!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")}),C?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(T,{status:L})}),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(D,{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:H(b??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} ${C?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:()=>h(c=>!c),"aria-label":u?n("common.collapse","Collapse"):n("common.expand","Expand"),children:u?"▾":"▸"})]}),u&&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_${je(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:N(c.connectedAt,n)}),e.jsx("td",{children:c.lastSeen?N(c.lastSeen,n):"-"}),e.jsx("td",{children:c.lastCommandAt?N(c.lastCommandAt,n):"-"}),e.jsx("td",{children:!c.isServer&&e.jsx("button",{className:s.killBtn,onClick:()=>x({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} ${C?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:N(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} ${C?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:()=>v(!0),children:n("common.clear","Clear")})]}),e.jsx(Q,{entries:l})]}),e.jsx($,{open:y,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:S,onCancel:()=>!S&&v(!1),onConfirm:M}),e.jsx($,{open:!!d,title:n("connection.agents.kill.title","Kill agent?"),message:`"${d==null?void 0:d.name}" 프로세스를 강제 종료합니다. 해당 에이전트의 진행 중인 작업이 중단됩니다.`,cancelLabel:n("common.cancel","Cancel"),confirmLabel:n("connection.agents.kill","Kill"),loading:m,onCancel:()=>!m&&x(null),onConfirm:q})]})}export{Se as Component};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{u as _,r as x,j as e}from"./index-
|
|
1
|
+
import{u as _,r as x,j as e}from"./index-FfT2oWAB.js";const N="_container_uv8oc_2",j="_header_uv8oc_10",v="_modeBtn_uv8oc_18",g="_modeBtnActive_uv8oc_33",b="_unifiedView_uv8oc_40",w="_diffLine_uv8oc_46",L="_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:b,diffLine:w,lineNum:L,lineContent:C,lineAdded:S,lineRemoved:V,lineContext:B,sideBySide:$,sidePane:A,sideLabel:P,sideContent:R,empty:D};function k(n,i){const o=n.split(`
|
|
2
2
|
`),d=i.split(`
|
|
3
3
|
`),a=[],f=Math.max(o.length,d.length);let t=0,l=0;for(;(t<o.length||l<d.length)&&(t<o.length&&l<d.length?o[t]===d[l]?(a.push({type:"context",content:o[t],lineNum:l+1}),t++,l++):(a.push({type:"removed",content:o[t],lineNum:t+1}),t++,t<o.length&&o[t]===d[l]?(a.push({type:"added",content:d[l],lineNum:l+1}),l++):l<d.length&&(a.push({type:"added",content:d[l],lineNum:l+1}),l++)):t<o.length?(a.push({type:"removed",content:o[t],lineNum:t+1}),t++):l<d.length&&(a.push({type:"added",content:d[l],lineNum:l+1}),l++),!(a.length>f*3)););return a}function O({before:n,after:i}){const{t:o}=_(),[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):"",l=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:o("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:o("changelog.diff.unified","Unified")}),e.jsx("button",{className:`${s.modeBtn} ${d==="side-by-side"?s.modeBtnActive:""}`,onClick:()=>a("side-by-side"),children:o("changelog.diff.sideBySide","Side by Side")})]}),d==="unified"?e.jsx("div",{className:s.unifiedView,children:l.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:o("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-
|
|
1
|
+
import{j as r,T as e}from"./index-FfT2oWAB.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-BPAvjNNu.js";import{I as V}from"./InfoLabel-BJIFNYA5.js";import{S as A}from"./StatusBadge-ilvVufN2.js";import{T as U}from"./TooltipText-bSKcc3-P.js";import{G as z}from"./GameChangeDetail-Bk8YUy4G.js";import{u as O,f as X}from"./useLiveUptime-HYmdQdHf.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-FfT2oWAB.js";import{I as V}from"./InfoLabel-B9KT3kfU.js";import{S as A}from"./StatusBadge-Bxe88ki2.js";import{T as U}from"./TooltipText-Baw38jOU.js";import{G as z}from"./GameChangeDetail-D1kE2L_v.js";import{u as O,f as X}from"./useLiveUptime-DhJz484L.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 v,u as S,j as e,k as H,l as D,m as E,o as U}from"./index-
|
|
1
|
+
import{r as n,a as v,u as S,j as e,k as H,l as D,m as E,o as U}from"./index-FfT2oWAB.js";import{D as $,T as O}from"./TierComparison-Dyf-knpe.js";import{I as P}from"./InfoLabel-B9KT3kfU.js";import{T as _}from"./TooltipText-Baw38jOU.js";import{C as F}from"./ConfirmModal-CmJCz5rg.js";const W=5e3;function V(t){const r=(t==null?void 0:t.enabled)??!0,[d,o]=n.useState([]),[a,l]=n.useState(null),[m,i]=n.useState(r),c=n.useRef(null),h=n.useCallback(async()=>{try{const x=await v.get("/api/dashboard/playtest/history");o(x.entries??[])}catch{}},[]),p=n.useCallback(async()=>{if(!r){i(!1);return}await h(),i(!1)},[r,h]),y=n.useCallback(async()=>{r&&(await v.post("/api/dashboard/playtest/history/clear"),o([]),l(null))},[r]),j=n.useCallback(async x=>{if(r)try{const w=await v.get(`/api/dashboard/playtest/report/${x}`);l(w)}catch{l(null)}},[r]);return n.useEffect(()=>{if(!r){i(!1);return}return p(),c.current=setInterval(p,W),()=>{c.current&&clearInterval(c.current)}},[r,p]),{history:d,selectedReport:a,loading:m,loadReport:j,clearHistory:y}}function Y(t){const r="2026-03-27T15:26:00.000Z",d={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:d}],report:{markdown:t("playtest.sample.report.markdown",`# Sample Arena Smoke Test
|
|
2
2
|
|
|
3
3
|
- Spawn flow: PASS
|
|
4
4
|
- HUD countdown: PASS
|