@weppy/roblox-mcp 2.6.4 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +27 -0
  3. package/README.md +22 -11
  4. package/install.ps1 +85 -19
  5. package/install.sh +64 -18
  6. package/llms-full.txt +1 -2
  7. package/llms.txt +4 -3
  8. package/package.json +1 -1
  9. package/plugins/weppy-roblox-mcp/.claude-plugin/plugin.json +1 -1
  10. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ChangelogDetailPage-DYQthxhC.js → ChangelogDetailPage-CIarzJIx.js} +1 -1
  11. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogPage-C1uCKyqh.js +1 -0
  12. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogPage-CNxAGfwG.css +1 -0
  13. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ConfirmModal-CM3ElkBC.js → ConfirmModal-BDWSInRi.js} +1 -1
  14. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ConnectionPage-DdKcJZt6.js → ConnectionPage-CWDwVCKg.js} +1 -1
  15. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{GameChangeDetail-DGphCFbI.js → GameChangeDetail-Bk8YUy4G.js} +1 -1
  16. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{InfoLabel-CMSu30c4.js → InfoLabel-BJIFNYA5.js} +1 -1
  17. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{OverviewPage-DM74adCU.js → OverviewPage-Di0p7YY2.js} +1 -1
  18. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/PlaytestPage-Dxgz0SKW.js +11 -0
  19. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SettingsPage-Cc9Wnj8M.css +1 -0
  20. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SettingsPage-DVgxRsfC.js +1 -0
  21. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{StatusBadge-BhRLY0yK.js → StatusBadge-ilvVufN2.js} +1 -1
  22. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{SyncPage-Col3nhBp.js → SyncPage-IICMnq8v.js} +1 -1
  23. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/Tabs-876h0_zB.css +1 -0
  24. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/Tabs-pDS5zzr9.js +1 -0
  25. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierComparison-BXMCd1IB.js +2 -0
  26. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ToolsPage-B3fMk-22.css +1 -0
  27. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ToolsPage-DEhsoa36.js +1 -0
  28. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{TooltipText-Bnvm1FcC.js → TooltipText-bSKcc3-P.js} +1 -1
  29. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/UiStudioPage-BHhd3zUv.js +16 -0
  30. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/UiStudioPage-DQOd5VrU.css +1 -0
  31. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{WhatsNewPage-M1EeHSH-.js → WhatsNewPage-ErpENbsZ.js} +1 -1
  32. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/index-BPAvjNNu.js +343 -0
  33. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/index-Gu7et1DX.css +1 -0
  34. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/sample-requests-Bx1zpYdG.css +1 -0
  35. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/sample-requests-DDQ3XchF.js +1 -0
  36. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ui-studio-sample-DrNTD6yi.png +0 -0
  37. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{useLiveUptime-Dc2iJiFi.js → useLiveUptime-HYmdQdHf.js} +1 -1
  38. package/plugins/weppy-roblox-mcp/dashboard/dist/index.html +2 -2
  39. package/plugins/weppy-roblox-mcp/dist/index.js +450 -85
  40. package/plugins/weppy-roblox-mcp/roblox-plugin/WeppyRobloxMCP.rbxm +0 -0
  41. package/.gitattributes +0 -1
  42. package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -60
  43. package/.github/ISSUE_TEMPLATE/feature_request.yml +0 -30
  44. package/.github/ISSUE_TEMPLATE/install_help.yml +0 -48
  45. package/.github/PULL_REQUEST_TEMPLATE.md +0 -16
  46. package/.github/workflows/install-test.yml +0 -140
  47. package/Dockerfile +0 -13
  48. package/docs/assets/screenshots/antigravity/antigravity_mcp_raw.png +0 -0
  49. package/docs/assets/screenshots/antigravity/antigravity_mcp_services_menu.png +0 -0
  50. package/docs/assets/screenshots/antigravity/antigravity_raw_config_menu.png +0 -0
  51. package/docs/assets/screenshots/dashboard/dashboard_changelog1.png +0 -0
  52. package/docs/assets/screenshots/dashboard/dashboard_changelog2.png +0 -0
  53. package/docs/assets/screenshots/dashboard/dashboard_connection.png +0 -0
  54. package/docs/assets/screenshots/dashboard/dashboard_overview.png +0 -0
  55. package/docs/assets/screenshots/dashboard/dashboard_playtest.png +0 -0
  56. package/docs/assets/screenshots/dashboard/dashboard_sync.png +0 -0
  57. package/docs/assets/screenshots/dashboard/dashboard_tools.png +0 -0
  58. package/docs/assets/screenshots/plugin/connection/connection-guide.png +0 -0
  59. package/docs/assets/screenshots/plugin/installation/main-screen.png +0 -0
  60. package/docs/assets/screenshots/plugin/installation/plugins-menu.png +0 -0
  61. package/docs/assets/screenshots/plugin/installation/settings-screen.png +0 -0
  62. package/docs/assets/screenshots/plugin/installation/toolbar-button.png +0 -0
  63. package/docs/assets/screenshots/plugin/license/dashboard-license-screen.png +0 -0
  64. package/docs/assets/screenshots/plugin/license/plugin-license-screen.png +0 -0
  65. package/docs/assets/screenshots/plugin/sync/sync-conflict.png +0 -0
  66. package/docs/assets/screenshots/plugin/sync/sync-main.png +0 -0
  67. package/docs/assets/screenshots/plugin/sync/sync-overview.png +0 -0
  68. package/docs/assets/screenshots/roblox-explorer/roblox-explorer-property-window.png +0 -0
  69. package/docs/assets/screenshots/roblox-explorer/roblox-explorer-screen.png +0 -0
  70. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogPage-BH87M2hn.css +0 -1
  71. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogPage-WFqQ5h8e.js +0 -1
  72. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/PlaytestPage-Dq3kV_rX.js +0 -11
  73. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SettingsPage-DTv0NbEY.css +0 -1
  74. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SettingsPage-QQd8aPdd.js +0 -1
  75. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierComparison-CYfIb0tr.js +0 -1
  76. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ToolsPage-54vIMfZg.css +0 -1
  77. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ToolsPage-Ba_6GnUZ.js +0 -1
  78. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/index-B-nqZCE3.js +0 -380
  79. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/index-COXUWuq2.css +0 -1
@@ -1 +1 @@
1
- import{r,a as R,u as M,b as B,c as V,j as e}from"./index-B-nqZCE3.js";import{I as G}from"./InfoLabel-CMSu30c4.js";import{G as D}from"./GameChangeDetail-DGphCFbI.js";import{T as m}from"./TooltipText-Bnvm1FcC.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-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};
@@ -0,0 +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-BPAvjNNu.js";import{C as G}from"./ConfirmModal-BDWSInRi.js";import{T as I}from"./TooltipText-bSKcc3-P.js";import{T as H}from"./Tabs-pDS5zzr9.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};
@@ -0,0 +1 @@
1
+ ._card_1n89u_2{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:14px 18px;cursor:pointer;transition:border-color var(--transition),box-shadow var(--transition)}._card_1n89u_2:hover{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent-dim)}._header_1n89u_17{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}._statusBadge_1n89u_24{display:flex;align-items:center;gap:6px;font-family:var(--font-label);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.05em}._statusDot_1n89u_35{width:7px;height:7px;border-radius:50%}._active_1n89u_41 ._statusDot_1n89u_35{background:var(--success);box-shadow:0 0 6px var(--success)}._active_1n89u_41{color:var(--success)}._completed_1n89u_50 ._statusDot_1n89u_35{background:var(--text-muted)}._completed_1n89u_50{color:var(--text-secondary)}._timeRange_1n89u_58{font-family:var(--font-code);font-size:11px;color:var(--text-secondary)}._summaryList_1n89u_65{display:flex;flex-direction:column;gap:4px}._summaryItem_1n89u_71{display:flex;align-items:center;gap:8px;font-family:var(--font-code);font-size:12px;color:var(--text-primary)}._summaryIcon_1n89u_80{width:20px;text-align:center;flex-shrink:0}._summaryText_1n89u_86{color:var(--text-secondary)}._progressBar_1n89u_91{margin-top:10px;height:3px;background:var(--bg-secondary);border-radius:2px;overflow:hidden}._progressFill_1n89u_99{height:100%;background:var(--accent);border-radius:2px;animation:_pulse_1n89u_1 2s ease-in-out infinite}@keyframes _pulse_1n89u_1{0%,to{opacity:.6;width:30%}50%{opacity:1;width:70%}}._emptySummary_1n89u_112{font-family:var(--font-label);font-size:12px;color:var(--text-muted);text-align:center;padding:8px 0}._contextBlock_1n89u_120{margin-top:12px;padding-top:12px;border-top:1px solid var(--border);display:flex;flex-direction:column;gap:4px}._contextLabel_1n89u_129{font-family:var(--font-label);font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-muted)}._contextValue_1n89u_137{font-family:var(--font-label);font-size:12px;color:var(--text-primary);line-height:1.5}._page_1ynbw_2{display:flex;flex-direction:column;gap:var(--content-gap);max-width:var(--content-max)}._limitNotice_1ynbw_9{padding:14px 16px;border:1px solid var(--pro-border);border-radius:var(--radius);background:linear-gradient(180deg,rgba(240,189,88,.12),transparent 58%),var(--bg-card)}._limitNoticeTitle_1ynbw_18{font-family:var(--font-label);font-size:12px;color:var(--pro-text);margin-bottom:6px}._limitNoticeText_1ynbw_25{font-size:12px;color:var(--text-secondary);line-height:1.5}._clearButton_1ynbw_33{border:1px solid var(--danger-border);background:var(--danger-bg);color:var(--danger-text);border-radius:var(--radius-sm);padding:6px 12px;font-family:var(--font-label);font-size:12px;font-weight:500;cursor:pointer;transition:background var(--transition),border-color var(--transition)}._clearButton_1ynbw_33:hover{background:var(--danger-hover-bg);border-color:var(--danger)}._list_1ynbw_54{display:flex;flex-direction:column;gap:10px}._empty_1ynbw_61{text-align:center;padding:40px 20px;color:var(--text-muted);font-family:var(--font-label);font-size:13px}._loading_1ynbw_70{text-align:center;padding:40px 20px;color:var(--text-secondary);font-family:var(--font-label);font-size:12px}._pagination_1ynbw_79{display:flex;align-items:center;justify-content:center;gap:12px;margin-top:4px}._pageInfo_1ynbw_87{font-family:var(--font-code);font-size:12px;color:var(--text-secondary)}._btn_1ynbw_93{font-family:var(--font-label);font-size:12px;padding:4px 12px;border-radius:4px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-primary);cursor:pointer;transition:background var(--transition),border-color var(--transition)}._btn_1ynbw_93:hover:not(:disabled){border-color:var(--accent);background:var(--accent-dim)}._btn_1ynbw_93:disabled{opacity:.4;cursor:default}
@@ -1 +1 @@
1
- import{j as s,s as e}from"./index-B-nqZCE3.js";function x({open:c,title:i,message:n,cancelLabel:t,confirmLabel:o,loading:a=!1,onCancel:l,onConfirm:r}){return c?s.jsx("div",{className:e.backdrop,onClick:a?void 0:l,children:s.jsxs("div",{className:e.modal,onClick:d=>d.stopPropagation(),children:[s.jsx("h2",{className:e.title,children:i}),s.jsx("p",{className:e.message,children:n}),s.jsxs("div",{className:e.actions,children:[s.jsx("button",{className:e.cancelButton,onClick:l,disabled:a,children:t}),s.jsx("button",{className:e.confirmButton,onClick:r,disabled:a,children:a?"...":o})]})]})}):null}export{x as C};
1
+ import{j as s,w as e}from"./index-BPAvjNNu.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,k as P}from"./index-B-nqZCE3.js";import{I as r}from"./InfoLabel-CMSu30c4.js";import{S as T}from"./StatusBadge-BhRLY0yK.js";import{T as D}from"./TooltipText-Bnvm1FcC.js";import{C as $}from"./ConfirmModal-CM3ElkBC.js";import{u as F,f as H}from"./useLiveUptime-Dc2iJiFi.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-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,4 +1,4 @@
1
- import{u as _,r as x,j as e}from"./index-B-nqZCE3.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(`
1
+ import{u as _,r as x,j as e}from"./index-BPAvjNNu.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-B-nqZCE3.js";function s({label:t,tooltip:o}){return r.jsx(e,{text:o,children:t})}export{s as I};
1
+ import{j as r,T as e}from"./index-BPAvjNNu.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,i as L,a as M,D as F}from"./index-B-nqZCE3.js";import{I as V}from"./InfoLabel-CMSu30c4.js";import{S as A}from"./StatusBadge-BhRLY0yK.js";import{T as U}from"./TooltipText-Bnvm1FcC.js";import{G as z}from"./GameChangeDetail-DGphCFbI.js";import{u as O,f as X}from"./useLiveUptime-Dc2iJiFi.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-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};
@@ -0,0 +1,11 @@
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-BPAvjNNu.js";import{D as $,T as O}from"./TierComparison-BXMCd1IB.js";import{I as P}from"./InfoLabel-BJIFNYA5.js";import{T as _}from"./TooltipText-bSKcc3-P.js";import{C as F}from"./ConfirmModal-BDWSInRi.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
+
3
+ - Spawn flow: PASS
4
+ - HUD countdown: PASS
5
+ - Wave bootstrap: PASS
6
+
7
+ This is a sample preview. Upgrade to Pro to save and review real automated playtest reports.`),logs:t("playtest.sample.report.logs",`[sample] boot playtest preview
8
+ [sample] spawn protection active
9
+ [sample] hud countdown rendered
10
+ [sample] wave one completed
11
+ [sample] preview report finished`),contextId:"sample_playtest_preview",contextSummary:d}}}const z="_page_wjm6d_2",G="_sampleBanner_wjm6d_9",Z="_sampleBannerRow_wjm6d_21",q="_sampleBannerMain_wjm6d_28",J="_sampleBadge_wjm6d_35",K="_sampleTitle_wjm6d_50",Q="_sampleMessage_wjm6d_57",X="_sampleActions_wjm6d_64",ee="_primaryAction_wjm6d_72",te="_secondaryAction_wjm6d_73",se="_card_wjm6d_109",ae="_cardHeader_wjm6d_116",re="_clearButton_wjm6d_128",oe="_statusRow_wjm6d_143",ne="_statusIndicator_wjm6d_150",le="_statusRunning_wjm6d_158",ie="_statusPaused_wjm6d_163",ce="_statusNotRunning_wjm6d_167",de="_statusLabel_wjm6d_171",me="_statusMeta_wjm6d_178",pe="_controlButtons_wjm6d_184",ue="_btn_wjm6d_191",he="_btnPrimary_wjm6d_213",ye="_btnDanger_wjm6d_223",_e="_historyList_wjm6d_233",xe="_historyItem_wjm6d_241",je="_historyItemSelected_wjm6d_260",we="_historyItemHeader_wjm6d_265",ge="_historyIcon_wjm6d_271",ve="_historyTimestamp_wjm6d_276",Se="_historyName_wjm6d_283",fe="_historyItemMeta_wjm6d_293",be="_historyMode_wjm6d_302",Ne="_historyDuration_wjm6d_306",Ce="_historyStatus_wjm6d_310",Le="_status_passed_wjm6d_317",Ie="_status_failed_wjm6d_321",Pe="_status_running_wjm6d_325",Re="_historyError_wjm6d_329",Be="_historyContext_wjm6d_339",Te="_historyContextLine_wjm6d_348",Me="_historyContextLabel_wjm6d_354",ke="_reportContainer_wjm6d_363",Ae="_reportContextPanel_wjm6d_369",He="_reportContextRow_wjm6d_379",De="_reportContextLabel_wjm6d_387",Ee="_reportSection_wjm6d_395",Ue="_reportSectionHeader_wjm6d_401",$e="_reportMarkdown_wjm6d_413",Oe="_reportLogs_wjm6d_426",Fe="_emptyState_wjm6d_441",We="_emptyStateTitle_wjm6d_448",Ve="_emptyStateMessage_wjm6d_456",Ye="_upgradePanel_wjm6d_465",ze="_upgradePanelIcon_wjm6d_473",Ge="_upgradePanelTitle_wjm6d_478",Ze="_upgradePanelDesc_wjm6d_486",qe="_benefitList_wjm6d_496",Je="_benefitItem_wjm6d_507",Ke="_upgradeActions_wjm6d_522",s={page:z,sampleBanner:G,sampleBannerRow:Z,sampleBannerMain:q,sampleBadge:J,sampleTitle:K,sampleMessage:Q,sampleActions:X,primaryAction:ee,secondaryAction:te,card:se,cardHeader:ae,clearButton:re,statusRow:oe,statusIndicator:ne,statusRunning:le,statusPaused:ie,statusNotRunning:ce,statusLabel:de,statusMeta:me,controlButtons:pe,btn:ue,btnPrimary:he,btnDanger:ye,historyList:_e,historyItem:xe,historyItemSelected:je,historyItemHeader:we,historyIcon:ge,historyTimestamp:ve,historyName:Se,historyItemMeta:fe,historyMode:be,historyDuration:Ne,historyStatus:Ce,status_passed:Le,status_failed:Ie,status_running:Pe,historyError:Re,historyContext:Be,historyContextLine:Te,historyContextLabel:Me,reportContainer:ke,reportContextPanel:Ae,reportContextRow:He,reportContextLabel:De,reportSection:Ee,reportSectionHeader:Ue,reportMarkdown:$e,reportLogs:Oe,emptyState:Fe,emptyStateTitle:We,emptyStateMessage:Ve,upgradePanel:Ye,upgradePanelIcon:ze,upgradePanelTitle:Ge,upgradePanelDesc:Ze,benefitList:qe,benefitItem:Je,upgradeActions:Ke};function g(t){return t.trim().toLowerCase()}function Qe(t){switch(g(t)){case"passed":return"✅";case"failed":return"❌";case"running":return"⏱";default:return"❓"}}function Xe(t,r){switch(g(r)){case"run":return t("playtest.status.mode.run","Run");case"server":return t("playtest.status.mode.server","Server");case"edit":return t("playtest.status.mode.edit","Edit");case"play":return t("playtest.status.mode.play","Play");default:return r}}function et(t,r){switch(g(r)){case"passed":return t("playtest.history.status.passed","Passed");case"failed":return t("playtest.history.status.failed","Failed");case"running":return t("playtest.history.status.running","Running");default:return t("playtest.history.status.unknown","Unknown")}}function tt(t){return t<1e3?`${t}ms`:`${(t/1e3).toFixed(1)}s`}function st({entries:t,onSelect:r,selectedTimestamp:d}){const{t:o}=S();return t.length===0?e.jsx("div",{className:s.emptyState,children:o("playtest.history.empty","No test results yet")}):e.jsx("div",{className:s.historyList,children:t.map(a=>{var m,i,c,h,p,y;const l=a.timestamp===d;return e.jsxs("button",{className:`${s.historyItem} ${l?s.historyItemSelected:""}`,onClick:()=>r(a.timestamp),children:[e.jsxs("div",{className:s.historyItemHeader,children:[e.jsx("span",{className:s.historyIcon,children:Qe(a.status)}),e.jsx("span",{className:s.historyTimestamp,children:a.timestamp}),e.jsx("span",{className:s.historyName,children:a.testName})]}),e.jsxs("div",{className:s.historyItemMeta,children:[e.jsx(_,{text:o("playtest.history.mode.tooltip","Playtest mode used for this recorded test run."),children:e.jsxs("span",{className:s.historyMode,children:[o("playtest.history.mode","Mode"),": ",Xe(o,a.mode)]})}),e.jsx("span",{className:s.historyDuration,children:tt(a.durationMs)}),e.jsx(_,{text:o("playtest.history.status.tooltip","Recorded result state for this automated playtest run."),children:e.jsx("span",{className:`${s.historyStatus} ${s[`status_${g(a.status)}`]??""}`,children:et(o,a.status)})})]}),a.errorMessage&&e.jsx("div",{className:s.historyError,children:a.errorMessage}),(a.contextId||((m=a.contextSummary)==null?void 0:m.testScenario)||((i=a.contextSummary)==null?void 0:i.expectedBehavior)||((c=a.contextSummary)==null?void 0:c.observedBehavior))&&e.jsxs("div",{className:s.historyContext,children:[a.contextId&&e.jsxs("div",{className:s.historyContextLine,children:[e.jsx("span",{className:s.historyContextLabel,children:o("playtest.context.contextId","Context ID")}),e.jsx("span",{children:a.contextId})]}),((h=a.contextSummary)==null?void 0:h.testScenario)&&e.jsxs("div",{className:s.historyContextLine,children:[e.jsx("span",{className:s.historyContextLabel,children:o("playtest.context.why","Why this test ran")}),e.jsx("span",{children:a.contextSummary.testScenario})]}),((p=a.contextSummary)==null?void 0:p.expectedBehavior)&&e.jsxs("div",{className:s.historyContextLine,children:[e.jsx("span",{className:s.historyContextLabel,children:o("playtest.context.expected","Expected")}),e.jsx("span",{children:a.contextSummary.expectedBehavior})]}),((y=a.contextSummary)==null?void 0:y.observedBehavior)&&e.jsxs("div",{className:s.historyContextLine,children:[e.jsx("span",{className:s.historyContextLabel,children:o("playtest.context.observed","Observed")}),e.jsx("span",{children:a.contextSummary.observedBehavior})]})]})]},a.timestamp)})})}function at({report:t}){var o,a,l,m,i,c;const{t:r}=S(),d=!!((o=t.contextSummary)!=null&&o.testScenario||(a=t.contextSummary)!=null&&a.expectedBehavior||(l=t.contextSummary)!=null&&l.observedBehavior);return e.jsxs("div",{className:s.reportContainer,children:[d&&e.jsxs("div",{className:s.reportContextPanel,children:[((m=t.contextSummary)==null?void 0:m.testScenario)&&e.jsxs("div",{className:s.reportContextRow,children:[e.jsx("span",{className:s.reportContextLabel,children:r("playtest.context.why","Why this test ran")}),e.jsx("span",{children:t.contextSummary.testScenario})]}),((i=t.contextSummary)==null?void 0:i.expectedBehavior)&&e.jsxs("div",{className:s.reportContextRow,children:[e.jsx("span",{className:s.reportContextLabel,children:r("playtest.context.expected","Expected")}),e.jsx("span",{children:t.contextSummary.expectedBehavior})]}),((c=t.contextSummary)==null?void 0:c.observedBehavior)&&e.jsxs("div",{className:s.reportContextRow,children:[e.jsx("span",{className:s.reportContextLabel,children:r("playtest.context.observed","Observed")}),e.jsx("span",{children:t.contextSummary.observedBehavior})]})]}),t.markdown&&e.jsxs("div",{className:s.reportSection,children:[e.jsx("div",{className:s.reportSectionHeader,children:e.jsx(_,{text:r("playtest.report.content.tooltip","Markdown summary for the selected automated playtest run."),children:e.jsx("span",{children:r("playtest.report.content","Report")})})}),e.jsx("pre",{className:s.reportMarkdown,children:t.markdown})]}),t.logs&&e.jsxs("div",{className:s.reportSection,children:[e.jsx("div",{className:s.reportSectionHeader,children:e.jsx(_,{text:r("playtest.report.logs.tooltip","Execution logs captured for the selected automated playtest run."),children:e.jsx("span",{children:r("playtest.report.logs","Logs")})})}),e.jsx("pre",{className:s.reportLogs,children:t.logs})]}),!t.markdown&&!t.logs&&e.jsx("div",{className:s.emptyState,children:r("playtest.report.empty","No report content available")})]})}function ct(){var L;const{t}=S(),{trackEvent:r}=H(),{tier:d,loading:o}=D(),a=!o&&d==="basic",l=V({enabled:!a}),{show:m}=E(),[i,c]=n.useState(null),[h,p]=n.useState(!1),[y,j]=n.useState(!1),[x,w]=n.useState(!1),{history:R,selectedReport:B,loading:T}=l,u=a?Y(t):null,f=((L=u==null?void 0:u.history[0])==null?void 0:L.timestamp)??null,b=a?i??f:i,N=(u==null?void 0:u.history)??R,C=u&&b===f?u.report:B,M=a?!1:T,k=I=>{c(I),!a&&l.loadReport(I)},A=async()=>{j(!0);try{await l.clearHistory(),m(t("toast.clearSuccess","Cleared successfully"),"success"),p(!1),c(null)}catch{m(t("toast.clearFailed","Failed to clear data"),"error")}finally{j(!1)}};return e.jsxs("div",{className:s.page,children:[a&&e.jsxs("div",{className:s.sampleBanner,children:[e.jsxs("div",{className:s.sampleBannerRow,children:[e.jsxs("div",{className:s.sampleBannerMain,children:[e.jsx("div",{className:s.sampleBadge,children:t("playtest.sample.badge","Preview of the Pro playtest view")}),e.jsx("div",{className:s.sampleTitle,children:t("playtest.sample.title","You are previewing the report viewer that becomes available after upgrading to Pro.")}),e.jsx("div",{className:s.sampleMessage,children:t("playtest.sample.message","This preview uses sample data. Real playtest history management and stored reports unlock with Pro.")})]}),e.jsxs("div",{className:s.sampleActions,children:[e.jsx("button",{className:s.secondaryAction,onClick:()=>{r("dashboard_click_event",{click_target:"tier_compare",placement:"playtest_sample_banner",page:"playtest"}),w(!0)},children:t("tier.compare","Basic vs Pro")}),e.jsx("a",{className:s.primaryAction,href:U.playtest,target:"_blank",rel:"noreferrer",onClick:()=>r("dashboard_click_event",{click_target:"upgrade_cta",placement:"playtest_sample_banner",page:"playtest"}),children:t("tier.upgrade","Upgrade to Pro")})]})]}),e.jsx($,{variant:"centered"})]}),e.jsxs("div",{className:s.card,children:[e.jsxs("div",{className:s.cardHeader,children:[e.jsx(P,{label:t("playtest.history.title","Test History"),tooltip:t("playtest.history.title.tooltip","Recorded automated playtest runs for this project.")}),a?e.jsx(_,{text:t("playtest.sample.clearDisabled","Upgrade to Pro to clear live playtest history."),children:e.jsx("span",{children:e.jsx("button",{className:s.clearButton,disabled:!0,children:t("common.clear","Clear")})})}):e.jsx("button",{className:s.clearButton,onClick:()=>p(!0),children:t("common.clear","Clear")})]}),M?e.jsx("div",{className:s.emptyState,children:t("common.loading","Loading...")}):N.length===0?e.jsxs("div",{className:s.emptyState,children:[e.jsx("div",{className:s.emptyStateTitle,children:t("playtest.empty.title","No playtest results yet")}),e.jsxs("div",{className:s.emptyStateMessage,children:[t("playtest.empty.message.before","Test results will appear here when the AI agent runs automated tests via")," ",e.jsx(_,{text:t("playtest.empty.runTest.tooltip","WEPPY Dashboard automation entry point that runs Roblox playtest checks through the system_info tool."),children:e.jsx("span",{children:"system_info.run_test"})}),t("playtest.empty.message.after",".")]})]}):e.jsx(st,{entries:N,onSelect:k,selectedTimestamp:b??void 0})]}),C&&e.jsxs("div",{className:s.card,children:[e.jsx("div",{className:s.cardHeader,children:e.jsx(P,{label:t("playtest.report.title","Selected Report"),tooltip:t("playtest.report.title.tooltip","Detailed output for the currently selected automated playtest run.")})}),e.jsx(at,{report:C})]}),!a&&e.jsx(F,{open:h,title:t("playtest.clear.title","Clear test history?"),message:t("playtest.clear.message","This permanently removes the stored playtest reports for the current place."),cancelLabel:t("common.cancel","Cancel"),confirmLabel:t("common.clear","Clear"),loading:y,onCancel:()=>!y&&p(!1),onConfirm:A}),x&&e.jsx(O,{onClose:()=>w(!1)})]})}export{ct as Component};
@@ -0,0 +1 @@
1
+ ._card_83d0e_4{border:1px solid var(--border);border-radius:var(--radius);background:var(--bg-card);padding:16px 20px;display:flex;flex-direction:column;gap:14px}._cardEmbedded_83d0e_14{border:none;border-radius:0;background:transparent;padding:14px 0 0}._cardTitle_83d0e_21{margin:0;font-size:13px;font-weight:600;color:var(--text-primary);letter-spacing:.02em}._usageRow_83d0e_30{display:flex;flex-direction:column;gap:4px}._usageTotal_83d0e_36{font-size:13px;font-weight:600;color:var(--text-primary)}._usageBreakdown_83d0e_42{font-size:12px;color:var(--text-muted)}._usageCounts_83d0e_47{font-size:12px;color:var(--text-secondary)}._divider_83d0e_53{border:none;border-top:1px solid var(--border);margin:0}._lastRunRow_83d0e_60{font-size:12px;color:var(--text-secondary);display:flex;align-items:center;gap:6px;flex-wrap:wrap}._lastRunLabel_83d0e_69{color:var(--text-muted);font-weight:500;white-space:nowrap}._errorIcon_83d0e_75{color:var(--error-text, #e05555);cursor:help;font-size:13px;line-height:1;position:relative}._errorIcon_83d0e_75:hover ._tooltip_83d0e_83{display:block}._tooltip_83d0e_83{display:none;position:absolute;bottom:calc(100% + 6px);left:50%;transform:translate(-50%);background:var(--bg-secondary);border:1px solid var(--border);border-radius:4px;padding:4px 8px;font-size:11px;color:var(--error-text, #e05555);white-space:nowrap;z-index:10;pointer-events:none;box-shadow:0 2px 8px #0003}._cleanupRow_83d0e_106{display:flex;flex-wrap:wrap;gap:8px;align-items:center}._cleanupLabel_83d0e_113{font-size:12px;color:var(--text-muted);font-weight:500;white-space:nowrap}._cleanupBtn_83d0e_120{padding:5px 10px;border-radius:5px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary);font-family:var(--font-label);font-size:11px;cursor:pointer;white-space:nowrap;transition:border-color var(--transition),color var(--transition)}._cleanupBtn_83d0e_120:hover:not(:disabled){border-color:var(--accent);color:var(--text-primary)}._cleanupBtn_83d0e_120:disabled{opacity:.45;cursor:not-allowed}._cleanupBtnDanger_83d0e_143{border-color:var(--error-border, rgba(224, 85, 85, .4));color:var(--error-text, #e05555)}._cleanupBtnDanger_83d0e_143:hover:not(:disabled){border-color:var(--error-text, #e05555);background:var(--error-bg, rgba(224, 85, 85, .08));color:var(--error-text, #e05555)}._retentionSection_83d0e_155{display:flex;flex-direction:column;gap:10px}._retentionTitle_83d0e_161{margin:0;font-size:12px;font-weight:600;color:var(--text-muted);letter-spacing:.04em;text-transform:uppercase}._retentionFieldset_83d0e_170{display:flex;flex-direction:column;gap:10px;border:none;margin:0;padding:0;position:relative}._retentionFieldset_83d0e_170[disabled]{opacity:.5;pointer-events:none}._proOverlay_83d0e_185{position:absolute;top:0;right:0;bottom:0;left:0;cursor:not-allowed;z-index:1}._proOverlay_83d0e_185:hover ._tooltip_83d0e_83{display:block}._radioRow_83d0e_197{display:flex;align-items:center;gap:8px;flex-wrap:wrap}._radioLabel_83d0e_204{display:flex;align-items:center;gap:5px;font-size:13px;color:var(--text-secondary);cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap}._radioLabel_83d0e_204 input[type=radio]{width:14px;height:14px;cursor:pointer;accent-color:var(--accent);flex-shrink:0}._presetGroup_83d0e_224{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-left:20px}._presetBtn_83d0e_232{padding:3px 8px;border-radius:4px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary);font-family:var(--font-label);font-size:11px;cursor:pointer;transition:border-color var(--transition),background var(--transition)}._presetBtn_83d0e_232:hover{border-color:var(--accent);color:var(--text-primary)}._presetBtnActive_83d0e_249{border-color:var(--accent);background:var(--accent-dim);color:var(--accent);font-weight:600}._freeInput_83d0e_256{width:72px;font-size:12px;padding:3px 7px;border:1px solid var(--border);border-radius:4px;background:var(--bg-secondary);color:var(--text-primary);font-family:inherit}._freeInput_83d0e_256:focus{outline:none;border-color:var(--accent)}._freeInput_83d0e_256._inputError_83d0e_272{border-color:var(--error-text, #e05555)}._inputUnit_83d0e_276{font-size:11px;color:var(--text-muted);white-space:nowrap}._cascadeRow_83d0e_283{display:flex;align-items:center;gap:7px;font-size:13px;color:var(--text-secondary);cursor:pointer;-webkit-user-select:none;user-select:none}._cascadeRow_83d0e_283 input[type=checkbox]{width:14px;height:14px;cursor:pointer;accent-color:var(--accent);flex-shrink:0}._retentionActions_83d0e_302{display:flex;gap:8px;flex-wrap:wrap}._saveBtn_83d0e_308{padding:6px 14px;border-radius:5px;border:1px solid transparent;background:var(--accent);color:var(--bg-card);font-family:var(--font-label);font-size:12px;font-weight:600;cursor:pointer;transition:opacity var(--transition)}._saveBtn_83d0e_308:hover:not(:disabled){opacity:.88}._saveBtn_83d0e_308:disabled{opacity:.45;cursor:not-allowed}._runNowBtn_83d0e_330{padding:6px 14px;border-radius:5px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-secondary);font-family:var(--font-label);font-size:12px;cursor:pointer;transition:border-color var(--transition),color var(--transition)}._runNowBtn_83d0e_330:hover:not(:disabled){border-color:var(--accent);color:var(--text-primary)}._runNowBtn_83d0e_330:disabled{opacity:.45;cursor:not-allowed}._errorMsg_83d0e_353{font-size:12px;color:var(--error-text, #e05555);padding:4px 0}._page_1uhow_2{display:flex;flex-direction:column;gap:16px;max-width:820px}._card_1uhow_10{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:16px 20px}._licenseCardPro_1uhow_17{border-color:var(--pro-border);background:linear-gradient(180deg,var(--pro-bg-soft),transparent 28%),var(--bg-card);box-shadow:inset 0 1px #f3d46b2e,0 0 0 1px #8f6f1f24}._cardHeader_1uhow_28{font-family:var(--font-label);font-weight:500;font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-secondary);margin-bottom:12px;display:flex;align-items:center;justify-content:space-between}._cardHeaderActions_1uhow_41{display:flex;align-items:center;gap:8px}._collapseButton_1uhow_47{width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--border);border-radius:4px;background:var(--bg-secondary);color:var(--text-secondary);font-size:12px;line-height:1;cursor:pointer;transition:border-color var(--transition),color var(--transition),background var(--transition)}._collapseButton_1uhow_47:hover{border-color:var(--accent);color:var(--text-primary)}._headerBadge_1uhow_69{font-size:10px;font-weight:400;padding:2px 8px;border-radius:4px;border:1px solid var(--border);color:var(--text-muted);text-transform:none;letter-spacing:0}._headerBadgeLive_1uhow_80{color:var(--success);border-color:var(--success)}._licenseGrid_1uhow_86{display:grid;grid-template-columns:auto 1fr;gap:6px 16px;font-family:var(--font-code);font-size:13px}._licenseGrid_1uhow_86 dt{color:var(--text-muted)}._licenseGrid_1uhow_86 dd{color:var(--text-primary);margin:0}._statusDot_1uhow_104{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:6px;vertical-align:middle}._statusActive_1uhow_113{background:var(--success);box-shadow:0 0 4px var(--success)}._statusGrace_1uhow_118{background:var(--warning, #b7791f);box-shadow:0 0 4px color-mix(in srgb,var(--warning, #b7791f) 70%,transparent)}._statusInactive_1uhow_123{background:var(--text-muted)}._statusError_1uhow_127{background:var(--error)}._proBadge_1uhow_132{color:var(--pro-badge);font-weight:500}._licenseCardPro_1uhow_17 ._cardHeader_1uhow_28 span:first-child{color:var(--pro-text)}._licenseCardPro_1uhow_17 ._licenseGrid_1uhow_86 dt{color:var(--pro-badge)}._upgradeLink_1uhow_146{display:inline-block;margin-top:8px;font-family:var(--font-label);font-size:12px;color:var(--accent);cursor:pointer;text-decoration:underline}._upgradeLink_1uhow_146:hover{opacity:.8}._licenseControls_1uhow_160{display:flex;flex-direction:column;gap:10px;margin-top:14px;padding-top:14px;border-top:1px solid var(--border)}._licenseControlRow_1uhow_169{display:flex;align-items:flex-end;gap:12px;flex-wrap:wrap}._licenseField_1uhow_176{display:flex;flex-direction:column;gap:6px}._licenseFieldGrow_1uhow_182{flex:1;min-width:220px}._controlLabel_1uhow_187{font-family:var(--font-label);font-size:12px;color:var(--text-primary)}._textInput_1uhow_193{font-family:var(--font-code);font-size:12px;padding:6px 8px;border-radius:4px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-primary);outline:none;transition:border-color var(--transition)}._textInput_1uhow_193:focus{border-color:var(--accent)}._actionBtn_1uhow_209{font-family:var(--font-label);font-size:12px;padding:6px 14px;border-radius:4px;border:1px solid var(--accent);background:transparent;color:var(--accent);cursor:pointer;transition:background var(--transition),color var(--transition),opacity var(--transition)}._actionBtn_1uhow_209:hover{background:var(--accent);color:var(--bg-primary)}._actionBtn_1uhow_209:disabled{opacity:.5;cursor:not-allowed}._licenseMessage_1uhow_231{margin:0;font-family:var(--font-code);font-size:12px;color:var(--text-secondary)}._licenseNotice_1uhow_238{margin:12px 0 0;padding:10px 12px;border-radius:8px;border:1px solid var(--border);font-family:var(--font-label);font-size:12px;line-height:1.5}._licenseNoticeInfo_1uhow_248{color:var(--text-primary);background:color-mix(in srgb,var(--accent) 8%,transparent);border-color:color-mix(in srgb,var(--accent) 28%,var(--border))}._licenseNoticeWarning_1uhow_254{color:var(--text-primary);background:color-mix(in srgb,var(--warning, #b7791f) 12%,transparent);border-color:color-mix(in srgb,var(--warning, #b7791f) 34%,var(--border))}._licenseNoticeMuted_1uhow_260{color:var(--text-secondary);background:var(--bg-secondary)}._settingRow_1uhow_266{display:flex;align-items:center;justify-content:space-between;padding:8px 0;border-bottom:1px solid var(--border);font-size:13px}._settingRow_1uhow_266:last-child{border-bottom:none}._settingLabel_1uhow_280{font-family:var(--font-label);color:var(--text-primary);flex:1}._settingControl_1uhow_287{display:flex;align-items:center;gap:8px;justify-content:flex-end;min-width:112px}._select_1uhow_296{font-family:var(--font-code);font-size:12px;padding:4px 8px;border-radius:4px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-primary);cursor:pointer;outline:none;transition:border-color var(--transition)}._select_1uhow_296:focus{border-color:var(--accent)}._numberInput_1uhow_314{font-family:var(--font-code);font-size:12px;padding:4px 8px;border-radius:4px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-primary);width:80px;outline:none;transition:border-color var(--transition)}._numberInput_1uhow_314:focus{border-color:var(--accent)}._toggleSwitch_1uhow_332{position:relative;display:inline-flex;align-items:center;cursor:pointer}._toggleInput_1uhow_339{position:absolute;opacity:0;width:1px;height:1px;pointer-events:none}._toggleTrack_1uhow_347{position:relative;display:inline-flex;align-items:center;width:46px;height:28px;padding:3px;border-radius:999px;border:1px solid color-mix(in srgb,var(--border) 82%,transparent);background:linear-gradient(180deg,#ffffff08,#fff0),color-mix(in srgb,var(--bg-secondary) 88%,#0b1220 12%);box-shadow:inset 0 1px #ffffff0d,inset 0 0 0 1px #070a122e;transition:background var(--transition),border-color var(--transition),box-shadow var(--transition),transform var(--transition)}._toggleThumb_1uhow_369{width:20px;height:20px;border-radius:50%;background:radial-gradient(circle at 30% 30%,#ffffffd1,#ffffff14 45%),linear-gradient(180deg,#f7fbff,#c8d4ea);box-shadow:0 4px 10px #00000047,inset 0 1px #ffffffa6;transform:translate(0);transition:transform var(--transition),background var(--transition),box-shadow var(--transition)}._toggleInput_1uhow_339:focus-visible+._toggleTrack_1uhow_347{border-color:color-mix(in srgb,var(--accent) 70%,white 8%);box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 24%,transparent),inset 0 1px #ffffff0d}._toggleInput_1uhow_339:checked+._toggleTrack_1uhow_347{border-color:color-mix(in srgb,var(--accent) 62%,white 6%);background:linear-gradient(180deg,color-mix(in srgb,var(--accent) 36%,white 4%),color-mix(in srgb,var(--accent) 78%,#1b2640 22%)),var(--accent);box-shadow:inset 0 1px #ffffff29,0 0 16px color-mix(in srgb,var(--accent) 22%,transparent)}._toggleInput_1uhow_339:checked+._toggleTrack_1uhow_347 ._toggleThumb_1uhow_369{transform:translate(18px);background:radial-gradient(circle at 30% 30%,#ffffffeb,#ffffff1f 42%),linear-gradient(180deg,#fff,#d8e5ff)}._toggleSwitch_1uhow_332:hover ._toggleTrack_1uhow_347{border-color:color-mix(in srgb,var(--accent) 38%,var(--border))}._toggleSwitch_1uhow_332:hover ._toggleInput_1uhow_339:checked+._toggleTrack_1uhow_347{box-shadow:inset 0 1px #ffffff29,0 0 20px color-mix(in srgb,var(--accent) 28%,transparent)}._savedIndicator_1uhow_418{font-family:var(--font-code);font-size:11px;color:var(--success);opacity:1;min-width:56px;text-align:right;white-space:nowrap;transition:opacity .3s ease}._savedIndicatorHidden_1uhow_429{opacity:0}._dataHistoryIntro_1uhow_434{margin:0 0 12px;font-family:var(--font-label);font-size:12px;line-height:1.5;color:var(--text-secondary)}._dataHistoryList_1uhow_442{display:flex;flex-direction:column;border-top:1px solid var(--border)}._dataHistoryRow_1uhow_448{display:grid;grid-template-columns:minmax(0,1fr) auto auto;align-items:center;gap:14px;padding:12px 0;border-bottom:1px solid var(--border)}._dataHistoryDetail_1uhow_457{padding:0 0 14px;border-bottom:1px solid var(--border)}._uiStudioDataHistoryRow_1uhow_462{border-bottom:none;padding-bottom:10px}._uiStudioDataHistoryDetail_1uhow_467{margin-left:16px;padding:12px 0 16px 16px;border-left:2px solid var(--border);background:linear-gradient(90deg,color-mix(in srgb,var(--bg-secondary) 42%,transparent),transparent 58%)}._dataHistoryMain_1uhow_474{min-width:0}._dataHistoryTitle_1uhow_478{font-family:var(--font-label);font-size:13px;color:var(--text-primary)}._dataHistoryDescription_1uhow_484{margin-top:3px;font-family:var(--font-label);font-size:12px;line-height:1.45;color:var(--text-muted)}._dataHistoryMetric_1uhow_492{font-family:var(--font-code);font-size:12px;color:var(--text-secondary);white-space:nowrap}._dataHistoryActions_1uhow_499{display:flex;align-items:center;gap:8px}._linkButton_1uhow_505,._dangerButton_1uhow_506{font-family:var(--font-label);font-size:12px;line-height:1;padding:7px 10px;border-radius:4px;text-decoration:none;cursor:pointer;transition:background var(--transition),color var(--transition),border-color var(--transition),opacity var(--transition)}._linkButton_1uhow_505{color:var(--accent);border:1px solid var(--border);background:transparent}._linkButton_1uhow_505:hover{border-color:var(--accent)}._dangerButton_1uhow_506{color:var(--error-text);border:1px solid var(--error-border);background:var(--error-bg)}._dangerButton_1uhow_506:hover{opacity:.86}._dangerButton_1uhow_506:disabled{opacity:.45;cursor:not-allowed}._inlineStatus_1uhow_542{margin:12px 0 0;font-family:var(--font-code);font-size:12px;color:var(--text-secondary)}._coldGrid_1uhow_550{display:grid;grid-template-columns:auto 1fr;gap:6px 16px;font-family:var(--font-code);font-size:13px}._coldGrid_1uhow_550 dt{color:var(--text-muted)}._coldGrid_1uhow_550 dd{color:var(--text-primary);margin:0}._coldHint_1uhow_568{margin-top:10px;font-family:var(--font-label);font-size:12px;color:var(--text-muted);font-style:italic}._langRow_1uhow_577{display:flex;align-items:center;gap:12px;font-size:13px}._langRow_1uhow_577 label{font-family:var(--font-label);color:var(--text-primary)}._loading_1uhow_590{color:var(--text-muted);font-family:var(--font-code);font-size:13px;padding:32px 0;text-align:center}._unit_1uhow_599{font-family:var(--font-code);font-size:11px;color:var(--text-muted)}@media(max-width:720px){._dataHistoryRow_1uhow_448{grid-template-columns:minmax(0,1fr);align-items:stretch}._dataHistoryMetric_1uhow_492{white-space:normal}._dataHistoryActions_1uhow_499{justify-content:flex-start}._uiStudioDataHistoryDetail_1uhow_467{margin-left:0}}
@@ -0,0 +1 @@
1
+ import{d as oe,r as u,f as le,D as re,e as ce,g as de,h as ue,a as D,u as V,j as e,i as ge,k as pe,A as he,S as me}from"./index-BPAvjNNu.js";import{I as v}from"./InfoLabel-BJIFNYA5.js";import{T as p}from"./TooltipText-bSKcc3-P.js";import{C as ye}from"./ConfirmModal-BDWSInRi.js";import{D as ae,f as ie,r as xe,s as _e,a as ne,d as K,S as ee,b as ve}from"./sample-requests-DDQ3XchF.js";function be(){const{level:t}=oe(),[s,d]=u.useState(null),[j,n]=u.useState(null),[l,o]=u.useState(!1),[f,h]=u.useState(!0),[A,N]=u.useState(!1),[T,w]=u.useState(null),b="gumroad",y=t==="disconnected",x=u.useCallback(c=>{c&&n(i=>({...i,...c,maskedKey:c.maskedKey??(i==null?void 0:i.maskedKey),provider:c.provider??(i==null?void 0:i.provider)??b}))},[b]),H=u.useCallback(c=>{if(!c){n(null);return}n({...c,provider:c.provider??b})},[b]),k=u.useCallback(async()=>{try{return await le(b)}catch{return null}},[b]);u.useEffect(()=>{let c=!1;async function i(){try{const[m,_]=await Promise.all([D.get("/api/dashboard/settings").catch(()=>null),k()]);if(c)return;m&&d(m),_&&x(_)}catch{}finally{c||h(!1)}}return i(),()=>{c=!0}},[k,x]),u.useEffect(()=>{const c=new re;c.connect();const i=c.on("license",m=>{k().then(_=>{if(_){if((m==null?void 0:m.cleared)===!0){H(_);return}x(_)}})});return()=>{i(),c.disconnect()}},[k,x,H]);const S=u.useCallback((c,i)=>{w(c??i)},[]),E=u.useCallback(async c=>{if(y)return!1;if(!c.trim())return w("License key is required."),!1;N(!0);try{const i=await ce({provider:b,licenseKey:c.trim()});return x(i.license),S(i.message,i.ok?"License updated.":"License activation failed."),i.ok}catch{return w("License activation failed."),!1}finally{N(!1)}},[S,y,b,x]),C=u.useCallback(async()=>{if(!y){N(!0);try{const c=await de({provider:b});x(c.license),S(c.message,c.ok?"License updated.":"License refresh failed.")}catch{w("License refresh failed.")}finally{N(!1)}}},[S,y,b,x]),B=u.useCallback(async()=>{if(!y){N(!0);try{const c=await ue({provider:b});H(c.license),S(c.message,c.ok?"License reset.":"License reset failed.")}catch{w("License reset failed.")}finally{N(!1)}}},[S,y,b,H]),I=u.useCallback(async(c,i)=>{if(s){d(m=>m&&{...m,hot:{...m.hot,[c]:i}}),o(!0);try{await D.patch("/api/dashboard/settings",{[c]:i})}catch{d(m=>m&&{...m,hot:{...m.hot,[c]:s.hot[c]}})}finally{o(!1)}}},[s]);return{settings:s,license:j,saving:l,licenseProvider:b,licenseControlsDisabled:y,licenseSubmitting:A,licenseMessage:T,activateLicense:E,refreshLicense:C,resetLicense:B,updateHotSetting:I,loading:f}}const fe="_card_83d0e_4",Se="_cardEmbedded_83d0e_14",je="_cardTitle_83d0e_21",Ne="_usageRow_83d0e_30",Le="_usageTotal_83d0e_36",we="_usageBreakdown_83d0e_42",Ce="_usageCounts_83d0e_47",He="_divider_83d0e_53",ke="_lastRunRow_83d0e_60",Re="_lastRunLabel_83d0e_69",Te="_errorIcon_83d0e_75",Ee="_tooltip_83d0e_83",Ae="_cleanupRow_83d0e_106",Be="_cleanupLabel_83d0e_113",Ie="_cleanupBtn_83d0e_120",De="_cleanupBtnDanger_83d0e_143",Pe="_retentionSection_83d0e_155",Me="_retentionTitle_83d0e_161",$e="_retentionFieldset_83d0e_170",Ue="_proOverlay_83d0e_185",Oe="_radioRow_83d0e_197",ze="_radioLabel_83d0e_204",Fe="_presetGroup_83d0e_224",Ge="_presetBtn_83d0e_232",qe="_presetBtnActive_83d0e_249",We="_freeInput_83d0e_256",Ye="_inputError_83d0e_272",Ke="_inputUnit_83d0e_276",Ve="_cascadeRow_83d0e_283",Qe="_retentionActions_83d0e_302",Xe="_saveBtn_83d0e_308",Je="_runNowBtn_83d0e_330",Ze="_errorMsg_83d0e_353",r={card:fe,cardEmbedded:Se,cardTitle:je,usageRow:Ne,usageTotal:Le,usageBreakdown:we,usageCounts:Ce,divider:He,lastRunRow:ke,lastRunLabel:Re,errorIcon:Te,tooltip:Ee,cleanupRow:Ae,cleanupLabel:Be,cleanupBtn:Ie,cleanupBtnDanger:De,retentionSection:Pe,retentionTitle:Me,retentionFieldset:$e,proOverlay:Ue,radioRow:Oe,radioLabel:ze,presetGroup:Fe,presetBtn:Ge,presetBtnActive:qe,freeInput:We,inputError:Ye,inputUnit:Ke,cascadeRow:Ve,retentionActions:Qe,saveBtn:Xe,runNowBtn:Je,errorMsg:Ze};function et(t,s){return!!(t.mode==="off"&&s.mode!=="off"||t.mode==="age"&&s.mode==="age"&&(s.ageDays??0)<(t.ageDays??0)||t.mode==="size"&&s.mode==="size"&&(s.sizeMb??0)<(t.sizeMb??0)||!t.cascadeSnapshots&&s.cascadeSnapshots)}function te(t){return t.mode==="age"?Number.isInteger(t.ageDays)&&t.ageDays>=1&&t.ageDays<=365:t.mode==="size"?Number.isInteger(t.sizeMb)&&t.sizeMb>=50&&t.sizeMb<=1e4:!0}function tt(t,s){return t.mode===s.mode&&t.ageDays===s.ageDays&&t.sizeMb===s.sizeMb&&t.cascadeSnapshots===s.cascadeSnapshots}function O(t){return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:t<1024*1024*1024?`${(t/(1024*1024)).toFixed(1)} MB`:`${(t/(1024*1024*1024)).toFixed(2)} GB`}function st({placeId:t,tier:s,currentPolicy:d,onSaved:j}){const{t:n}=V(),[l,o]=u.useState(d),[f,h]=u.useState(()=>[7,14,30,90].includes(d.ageDays??-1)?"":String(d.ageDays??30)),[A,N]=u.useState(()=>[100,500,1e3].includes(d.sizeMb??-1)?"":String(d.sizeMb??500)),[T,w]=u.useState(null),[b,y]=u.useState(!1),[x,H]=u.useState(!1),[k,S]=u.useState(!1),[E,C]=u.useState(null);u.useEffect(()=>{o(d);const g=[7,14,30,90],R=[100,500,1e3];h(g.includes(d.ageDays??-1)?"":String(d.ageDays??30)),N(R.includes(d.sizeMb??-1)?"":String(d.sizeMb??500))},[d]);const B=s==="basic",I=te(l),c=tt(d,l),i=I&&!c&&!x,m=g=>{o(R=>{const U={...R,mode:g};return g==="age"&&(U.ageDays=parseInt(f,10)||30),g==="size"&&(U.sizeMb=parseInt(A,10)||500),U})},_=g=>{h(""),o(R=>({...R,ageDays:g}))},L=g=>{N(""),o(R=>({...R,sizeMb:g}))},z=g=>{h(g);const R=parseInt(g,10);Number.isNaN(R)||o(U=>({...U,ageDays:R}))},Q=g=>{N(g);const R=parseInt(g,10);Number.isNaN(R)||o(U=>({...U,sizeMb:R}))},M=async()=>{if(C(null),et(d,l)){try{const g=await ie(t,{mode:l.mode,ageDays:l.ageDays,sizeMb:l.sizeMb,cascadeSnapshots:l.cascadeSnapshots});w(g.dryRun),y(!0)}catch(g){C(g.message)}return}await Y()},Y=async()=>{H(!0);try{await _e(t,l),y(!1),j()}catch(g){throw C(g.message),g}finally{H(!1)}},X=async()=>{C(null),S(!0);try{await xe(t),j()}catch(g){C(g.message)}finally{S(!1)}},J=T?`${n("uiStudio.cleanup.policy.confirm.messageStrict","이 정책으로 즉시")} ${T.wouldRemoveRequests}${n("uiStudio.cleanup.policy.confirm.requests","건")} / ${T.wouldRemoveSnapshots}${n("uiStudio.cleanup.policy.confirm.snapshots","개 화면 캡처")} / ${O(T.wouldFreeBytes)} ${n("uiStudio.cleanup.policy.confirm.freed","가 삭제됩니다 — 적용?")}`:"",Z=l.mode==="age"&&!te(l),$=l.mode==="size"&&!te(l);return e.jsxs("div",{className:r.retentionSection,children:[e.jsx("h3",{className:r.retentionTitle,children:e.jsx(v,{label:n("uiStudio.cleanup.policy.title","자동 삭제 정책"),tooltip:n("uiStudio.cleanup.policy.title.tooltip","Rules that automatically remove old or large captures.")})}),e.jsxs("div",{style:{position:"relative"},children:[B&&e.jsx("div",{className:r.proOverlay,title:n("uiStudio.cleanup.policy.proRequired","Pro 업그레이드 후 사용 가능"),children:e.jsx("div",{className:r.tooltip,children:n("uiStudio.cleanup.policy.proRequired","Pro 업그레이드 후 사용 가능")})}),e.jsxs("fieldset",{className:r.retentionFieldset,disabled:B,style:B?{opacity:.45,pointerEvents:"none"}:void 0,children:[e.jsx("div",{className:r.radioRow,children:e.jsx(p,{text:n("uiStudio.cleanup.policy.modeOff.tooltip","Turn off auto-cleanup. Data stays until you remove it manually."),children:e.jsxs("label",{className:r.radioLabel,children:[e.jsx("input",{type:"radio",name:"cleanupMode",value:"off",checked:l.mode==="off",onChange:()=>m("off")}),n("uiStudio.cleanup.policy.modeOff","사용 안 함 (off)")]})})}),e.jsxs("div",{children:[e.jsx("div",{className:r.radioRow,children:e.jsx(p,{text:n("uiStudio.cleanup.policy.modeAge.tooltip","Automatically delete data older than the configured number of days."),children:e.jsxs("label",{className:r.radioLabel,children:[e.jsx("input",{type:"radio",name:"cleanupMode",value:"age",checked:l.mode==="age",onChange:()=>m("age")}),n("uiStudio.cleanup.policy.modeAge","기간 기반 (age)")]})})}),l.mode==="age"&&e.jsxs("div",{className:r.presetGroup,children:[[7,14,30,90].map(g=>e.jsx(p,{text:n("uiStudio.cleanup.policy.agePreset.tooltip","Delete data older than this many days."),children:e.jsxs("button",{type:"button",className:`${r.presetBtn} ${l.ageDays===g&&f===""?r.presetBtnActive:""}`,onClick:()=>_(g),children:[g,n("uiStudio.cleanup.policy.daysUnit","일")]})},g)),e.jsx(p,{text:n("uiStudio.cleanup.policy.ageInput.tooltip","Enter any value between 1 and 365 days."),children:e.jsx("input",{type:"number",className:`${r.freeInput} ${Z?r.inputError:""}`,value:f,min:1,max:365,onChange:g=>z(g.target.value)})}),e.jsxs("span",{className:r.inputUnit,children:["1–365",n("uiStudio.cleanup.policy.daysUnit","일")]})]})]}),e.jsxs("div",{children:[e.jsx("div",{className:r.radioRow,children:e.jsx(p,{text:n("uiStudio.cleanup.policy.modeSize.tooltip","When total usage exceeds the limit, the oldest data is removed first."),children:e.jsxs("label",{className:r.radioLabel,children:[e.jsx("input",{type:"radio",name:"cleanupMode",value:"size",checked:l.mode==="size",onChange:()=>m("size")}),n("uiStudio.cleanup.policy.modeSize","용량 기반 (size)")]})})}),l.mode==="size"&&e.jsxs("div",{className:r.presetGroup,children:[[100,500,1e3].map(g=>e.jsx(p,{text:n("uiStudio.cleanup.policy.sizePreset.tooltip","Keep total usage under this size."),children:e.jsxs("button",{type:"button",className:`${r.presetBtn} ${l.sizeMb===g&&A===""?r.presetBtnActive:""}`,onClick:()=>L(g),children:[g,n("uiStudio.cleanup.policy.mbUnit","MB")]})},g)),e.jsx(p,{text:n("uiStudio.cleanup.policy.sizeInput.tooltip","Enter any value between 50 MB and 10000 MB (10 GB)."),children:e.jsx("input",{type:"number",className:`${r.freeInput} ${$?r.inputError:""}`,value:A,min:50,max:1e4,onChange:g=>Q(g.target.value)})}),e.jsxs("span",{className:r.inputUnit,children:["50–10000",n("uiStudio.cleanup.policy.mbUnit","MB")]})]})]}),e.jsx(p,{text:n("uiStudio.cleanup.policy.cascade.tooltip","Also delete the capture images linked to those records. If off, the images stay."),children:e.jsxs("label",{className:r.cascadeRow,children:[e.jsx("input",{type:"checkbox",checked:l.cascadeSnapshots,onChange:g=>o(R=>({...R,cascadeSnapshots:g.target.checked}))}),n("uiStudio.cleanup.policy.cascade","연결된 화면 캡처도 함께 삭제")]})}),e.jsxs("div",{className:r.retentionActions,children:[e.jsx(p,{text:n("uiStudio.cleanup.policy.save.tooltip","Save the current cleanup rule. It runs in the background from then on."),children:e.jsx("button",{type:"button",className:r.saveBtn,onClick:()=>void M(),disabled:!i,children:n("uiStudio.cleanup.policy.save","정책 저장")})}),e.jsx(p,{text:n("uiStudio.cleanup.policy.runNow.tooltip","Run the current rule once now, without waiting for the next scheduled run."),children:e.jsx("button",{type:"button",className:r.runNowBtn,onClick:()=>void X(),disabled:k,children:n("uiStudio.cleanup.policy.runNow","지금 정리")})})]}),E&&e.jsx("div",{className:r.errorMsg,children:E})]})]}),b&&T&&e.jsx(ae,{title:n("uiStudio.cleanup.policy.confirm.title","정책 적용 확인"),message:J,danger:!0,confirmLabel:n("uiStudio.cleanup.policy.save","정책 저장"),busy:x,onConfirm:Y,onClose:()=>y(!1)})]})}function at({placeId:t,tier:s,onChanged:d,sampleUsage:j,sampleRetention:n,embedded:l=!1}){const{t:o}=V(),f=s==="basic"&&j!=null&&n!=null,[h,A]=u.useState(f?j:null),[N,T]=u.useState(f?n:null),[w,b]=u.useState(null),[y,x]=u.useState(null),[H,k]=u.useState(null),S=u.useCallback(async()=>{if(!f&&t!=null){b(null);try{const[_,L]=await Promise.all([ne(t),ie(t)]);A(_),T(L.policy)}catch(_){b(_.message)}}},[t,f]);u.useEffect(()=>{S()},[S]);const E=u.useCallback(()=>{S(),d==null||d()},[S,d]),C=u.useCallback(async()=>{if(y&&t!=null){k(null);try{y.kind==="keep7"?await K(t,{olderThanDays:7,alsoSnapshots:!0}):y.kind==="keep30"?await K(t,{olderThanDays:30,alsoSnapshots:!0}):await K(t,{all:!0,alsoSnapshots:!0}),x(null),S(),d==null||d()}catch(_){throw k(_.message),_}}},[y,t,S,d]);function B(_){const L=o("uiStudio.cleanup.studioPreservedNote","This deletes saved change records and screenshots on disk only; Roblox Studio instances are not affected.");return _.kind==="keep7"?`${o("uiStudio.cleanup.cleanupConfirmMessage.keep7","7일 이전 변경 기록과 화면 캡처가 삭제됩니다. 이 작업은 되돌릴 수 없습니다.")} ${L}`:_.kind==="keep30"?`${o("uiStudio.cleanup.cleanupConfirmMessage.keep30","30일 이전 변경 기록과 화면 캡처가 삭제됩니다. 이 작업은 되돌릴 수 없습니다.")} ${L}`:`${((h==null?void 0:h.requestCount)??0)+((h==null?void 0:h.snapshotCount)??0)}${o("uiStudio.cleanup.cleanupConfirmMessage.all","개의 저장된 변경 기록과 화면 캡처가 삭제됩니다. 이 작업은 되돌릴 수 없습니다.")} ${L}`}if(t==null&&!f)return null;if(w)return e.jsx("div",{className:`${r.card} ${l?r.cardEmbedded:""}`,children:e.jsx("p",{className:r.errorMsg,children:w})});if(!h||!N)return e.jsx("div",{className:`${r.card} ${l?r.cardEmbedded:""}`,children:e.jsx("p",{style:{fontSize:12,color:"var(--text-muted)",margin:0},children:o("uiStudio.storage.loading","로딩 중...")})});const I=N.lastRunAt,c=N.lastRunStats,i=I?new Date(I).toLocaleString():null,m=t??0;return e.jsxs("div",{className:`${r.card} ${l?r.cardEmbedded:""}`,children:[e.jsx("h3",{className:r.cardTitle,children:e.jsx(v,{label:o("uiStudio.storage.title","UI Studio 저장 데이터"),tooltip:o("uiStudio.storage.title.tooltip","Disk usage of UI Studio change records and screenshots.")})}),e.jsxs("div",{className:r.usageRow,children:[e.jsx(p,{text:o("uiStudio.storage.usageLabel.tooltip","Disk space currently used by UI Studio for this project."),children:e.jsxs("div",{className:r.usageTotal,children:[o("uiStudio.storage.usageLabel","사용 중")," ",O(h.totalBytes)]})}),e.jsxs("div",{className:r.usageBreakdown,children:[e.jsx(p,{text:o("uiStudio.storage.historyBytes.tooltip","Space taken by change record data (JSON)."),children:e.jsxs("span",{children:[o("uiStudio.storage.historyBytes","변경 이력")," ",O(h.historyBytes)]})})," · ",e.jsx(p,{text:o("uiStudio.storage.snapshotBytes.tooltip","Space taken by captured PNG image files."),children:e.jsxs("span",{children:[o("uiStudio.storage.snapshotBytes","화면 캡처")," ",O(h.snapshotBytes)]})})]}),e.jsxs("div",{className:r.usageCounts,children:[e.jsx(p,{text:o("uiStudio.storage.requestCount.tooltip","Number of actions where AI changed the UI."),children:e.jsxs("span",{children:[o("uiStudio.storage.requestCount","변경 기록")," ",h.requestCount.toLocaleString(),o("uiStudio.storage.countSuffix","개")]})})," · ",e.jsx(p,{text:o("uiStudio.storage.mutationCount.tooltip","Number of detail changes inside actions (one property edit = 1)."),children:e.jsxs("span",{children:[o("uiStudio.storage.mutationCount","변경 상세")," ",h.mutationCount.toLocaleString(),o("uiStudio.storage.countSuffix","개")]})})," · ",e.jsx(p,{text:o("uiStudio.storage.snapshotCount.tooltip","Number of saved capture image files."),children:e.jsxs("span",{children:[o("uiStudio.storage.snapshotCount","화면 캡처")," ",h.snapshotCount.toLocaleString(),o("uiStudio.storage.countSuffix","개")]})})]})]}),e.jsx("hr",{className:r.divider}),e.jsx(st,{placeId:m,tier:s,currentPolicy:N,onSaved:E}),e.jsx("hr",{className:r.divider}),e.jsxs("div",{className:r.lastRunRow,children:[e.jsx("span",{className:r.lastRunLabel,children:e.jsx(v,{label:o("uiStudio.storage.lastRun","마지막 자동 정리"),tooltip:o("uiStudio.storage.lastRun.tooltip","When the auto-cleanup policy last ran, and what it removed.")})}),i?e.jsxs(e.Fragment,{children:[e.jsx("span",{children:i}),c&&e.jsxs("span",{children:["· ",o("uiStudio.storage.requestCount","변경 기록")," ",c.removedRequests,o("uiStudio.storage.countSuffix","개")," / ",o("uiStudio.storage.snapshotCount","화면 캡처")," ",c.removedSnapshots,o("uiStudio.storage.countSuffix","개")," / ",O(c.freedBytes)," ",o("uiStudio.storage.lastRunFreed","회수")]}),c&&c.errors>0&&e.jsxs("span",{className:r.errorIcon,title:`${o("uiStudio.storage.lastRunErrors","오류")} ${c.errors}건`,children:["⚠",e.jsxs("span",{className:r.tooltip,children:[o("uiStudio.storage.lastRunErrors","오류")," ",c.errors,o("uiStudio.storage.countSuffix","건")]})]})]}):e.jsx("span",{children:o("uiStudio.storage.lastRunNever","—")})]}),e.jsx("hr",{className:r.divider}),e.jsxs("div",{className:r.cleanupRow,children:[e.jsx("span",{className:r.cleanupLabel,children:e.jsx(v,{label:o("uiStudio.cleanup.label","수동 정리"),tooltip:o("uiStudio.cleanup.label.tooltip","Manually clean up change records and captures whenever you want.")})}),e.jsx(p,{text:o("uiStudio.cleanup.keep7.tooltip","Delete change records and captures older than 7 days."),children:e.jsx("button",{type:"button",className:r.cleanupBtn,onClick:()=>x({kind:"keep7"}),disabled:s==="basic",children:o("uiStudio.cleanup.keepLastNDays","최근 7일만 남기기").replace("{n}","7")})}),e.jsx(p,{text:o("uiStudio.cleanup.keep30.tooltip","Delete change records and captures older than 30 days."),children:e.jsx("button",{type:"button",className:r.cleanupBtn,onClick:()=>x({kind:"keep30"}),disabled:s==="basic",children:o("uiStudio.cleanup.keepLastNDays","최근 30일만 남기기").replace("{n}","30")})}),e.jsx(p,{text:o("uiStudio.cleanup.deleteAll.tooltip","Delete every change record and capture for this project. The actual UI in Roblox Studio is not affected."),children:e.jsx("button",{type:"button",className:`${r.cleanupBtn} ${r.cleanupBtnDanger}`,onClick:()=>x({kind:"all"}),disabled:s==="basic",children:o("uiStudio.cleanup.deleteAll","전체 삭제…")})})]}),H&&e.jsx("div",{className:r.errorMsg,children:H}),y&&e.jsx(ae,{title:o("uiStudio.cleanup.cleanupConfirmTitle","정리 확인"),message:B(y),danger:!0,confirmLabel:o("common.delete","삭제"),onConfirm:C,onClose:()=>{x(null),k(null)}})]})}const it="_page_1uhow_2",nt="_card_1uhow_10",ot="_licenseCardPro_1uhow_17",lt="_cardHeader_1uhow_28",rt="_cardHeaderActions_1uhow_41",ct="_collapseButton_1uhow_47",dt="_headerBadge_1uhow_69",ut="_headerBadgeLive_1uhow_80",gt="_licenseGrid_1uhow_86",pt="_statusDot_1uhow_104",ht="_statusActive_1uhow_113",mt="_statusGrace_1uhow_118",yt="_statusInactive_1uhow_123",xt="_statusError_1uhow_127",_t="_proBadge_1uhow_132",vt="_upgradeLink_1uhow_146",bt="_licenseControls_1uhow_160",ft="_licenseControlRow_1uhow_169",St="_licenseField_1uhow_176",jt="_licenseFieldGrow_1uhow_182",Nt="_controlLabel_1uhow_187",Lt="_textInput_1uhow_193",wt="_actionBtn_1uhow_209",Ct="_licenseMessage_1uhow_231",Ht="_licenseNotice_1uhow_238",kt="_licenseNoticeInfo_1uhow_248",Rt="_licenseNoticeWarning_1uhow_254",Tt="_licenseNoticeMuted_1uhow_260",Et="_settingRow_1uhow_266",At="_settingLabel_1uhow_280",Bt="_settingControl_1uhow_287",It="_select_1uhow_296",Dt="_numberInput_1uhow_314",Pt="_toggleSwitch_1uhow_332",Mt="_toggleInput_1uhow_339",$t="_toggleTrack_1uhow_347",Ut="_toggleThumb_1uhow_369",Ot="_savedIndicator_1uhow_418",zt="_savedIndicatorHidden_1uhow_429",Ft="_dataHistoryIntro_1uhow_434",Gt="_dataHistoryList_1uhow_442",qt="_dataHistoryRow_1uhow_448",Wt="_dataHistoryDetail_1uhow_457",Yt="_uiStudioDataHistoryRow_1uhow_462",Kt="_uiStudioDataHistoryDetail_1uhow_467",Vt="_dataHistoryMain_1uhow_474",Qt="_dataHistoryTitle_1uhow_478",Xt="_dataHistoryDescription_1uhow_484",Jt="_dataHistoryMetric_1uhow_492",Zt="_dataHistoryActions_1uhow_499",es="_linkButton_1uhow_505",ts="_dangerButton_1uhow_506",ss="_inlineStatus_1uhow_542",as="_coldGrid_1uhow_550",is="_coldHint_1uhow_568",ns="_langRow_1uhow_577",os="_loading_1uhow_590",ls="_unit_1uhow_599",a={page:it,card:nt,licenseCardPro:ot,cardHeader:lt,cardHeaderActions:rt,collapseButton:ct,headerBadge:dt,headerBadgeLive:ut,licenseGrid:gt,statusDot:pt,statusActive:ht,statusGrace:mt,statusInactive:yt,statusError:xt,proBadge:_t,upgradeLink:vt,licenseControls:bt,licenseControlRow:ft,licenseField:St,licenseFieldGrow:jt,controlLabel:Nt,textInput:Lt,actionBtn:wt,licenseMessage:Ct,licenseNotice:Ht,licenseNoticeInfo:kt,licenseNoticeWarning:Rt,licenseNoticeMuted:Tt,settingRow:Et,settingLabel:At,settingControl:Bt,select:It,numberInput:Dt,toggleSwitch:Pt,toggleInput:Mt,toggleTrack:$t,toggleThumb:Ut,savedIndicator:Ot,savedIndicatorHidden:zt,dataHistoryIntro:Ft,dataHistoryList:Gt,dataHistoryRow:qt,dataHistoryDetail:Wt,uiStudioDataHistoryRow:Yt,uiStudioDataHistoryDetail:Kt,dataHistoryMain:Vt,dataHistoryTitle:Qt,dataHistoryDescription:Xt,dataHistoryMetric:Jt,dataHistoryActions:Zt,linkButton:es,dangerButton:ts,inlineStatus:ss,coldGrid:as,coldHint:is,langRow:ns,loading:os,unit:ls},rs={toolsActivity:null,toolStats:null,toolSessions:null,syncLog:null,playtestReports:null,projectChanges:null,connectionLog:null},cs={toolsActivity:null,toolStats:null,syncLog:null,playtestReports:null,projectChanges:null,connectionLog:null};function ds(t){var s;return t?t.pluginConnected?t.activePlaceId:t.lastActivePlaceId??((s=t.places[0])==null?void 0:s.placeId)??null:null}async function P(t){try{return await t}catch{return null}}function q(t){return t?typeof t.total=="number"?t.total:Array.isArray(t.entries)?t.entries.length:null:null}function W(t,s,d,j){return s===null?t("settings.dataHistory.metric.unavailable","Unavailable"):`${s.toLocaleString()} ${t(d,j)}`}function F(t,s,d){const j=d===null?t("settings.dataHistory.metric.sizeUnavailable","size unavailable"):O(d);return`${s} · ${j}`}function G(t,s){var j;const d=(j=t==null?void 0:t[s])==null?void 0:j.bytes;return typeof d=="number"&&Number.isFinite(d)?d:null}function us(t,s){return s?[`${s.requestCount.toLocaleString()} ${t("uiStudio.storage.requestCount","change records")}`,`${s.snapshotCount.toLocaleString()} ${t("uiStudio.storage.snapshotCount","screenshots")}`,O(s.totalBytes)].join(" · "):t("settings.dataHistory.metric.unavailable","Unavailable")}function gs({tier:t}){const{t:s}=V(),[d,j]=u.useState(rs),[n,l]=u.useState(cs),[o,f]=u.useState(t==="basic"?ee:null),[h,A]=u.useState(null),[N,T]=u.useState(!0),[w,b]=u.useState(!0),[y,x]=u.useState(null),[H,k]=u.useState(!1),[S,E]=u.useState(null),C=u.useCallback(async()=>{T(!0);const L=await P(ge()),z=ds(L);A(z);const[Q,M,Y,X,J,Z,$]=await Promise.all([P(D.get("/api/dashboard/history",{limit:"1",offset:"0"})),P(D.get("/api/dashboard/tool-stats")),P(D.get("/sync/history",{limit:"1",offset:"0"})),P(D.get("/api/dashboard/playtest/history")),P(D.get("/api/dashboard/changelog",{limit:"1",offset:"0"})),P(D.get("/api/dashboard/connection-log")),P(D.get("/api/dashboard/storage-summary"))]),g=t==="basic"?ee:z===null?null:await P(ne(z));j({toolsActivity:q(Q),toolStats:(M==null?void 0:M.totalCalls)??null,toolSessions:(M==null?void 0:M.totalSessions)??null,syncLog:q(Y),playtestReports:q(X),projectChanges:q(J),connectionLog:q(Z)}),l({toolsActivity:G($,"toolsActivity"),toolStats:G($,"toolStats"),syncLog:G($,"syncLog"),playtestReports:G($,"playtestReports"),projectChanges:G($,"projectChanges"),connectionLog:G($,"connectionLog")}),f(g),T(!1)},[t]);u.useEffect(()=>{C()},[C]);const B=u.useMemo(()=>[{key:"toolsActivity",title:s("settings.dataHistory.toolsActivity.title","Tool activity"),description:s("settings.dataHistory.toolsActivity.description","Saved tool runs shown on the Tools page."),metric:F(s,W(s,d.toolsActivity,"settings.dataHistory.metric.records","records"),n.toolsActivity),metricTooltip:s("settings.dataHistory.toolsActivity.metric.tooltip","Number of saved tool runs and the disk space they use."),route:"/tools",clearEndpoint:"/api/dashboard/tools/history/clear"},{key:"toolStats",title:s("settings.dataHistory.toolStats.title","Tool usage statistics"),description:s("settings.dataHistory.toolStats.description","Aggregated tool counts and status totals."),metric:F(s,d.toolStats===null?s("settings.dataHistory.metric.unavailable","Unavailable"):`${d.toolStats.toLocaleString()} ${s("settings.dataHistory.metric.runs","runs")} · ${(d.toolSessions??0).toLocaleString()} ${s("settings.dataHistory.metric.sessions","sessions")}`,n.toolStats),metricTooltip:s("settings.dataHistory.toolStats.metric.tooltip","Aggregated total runs and session counts."),route:"/tools",clearEndpoint:"/api/dashboard/tools/statistics/clear"},{key:"syncLog",title:s("settings.dataHistory.syncLog.title","Sync log"),description:s("settings.dataHistory.syncLog.description","Saved file sync events for the active place."),metric:F(s,W(s,d.syncLog,"settings.dataHistory.metric.records","records"),n.syncLog),metricTooltip:s("settings.dataHistory.syncLog.metric.tooltip","Number of saved sync events and the disk space they use."),route:"/sync",clearEndpoint:"/api/dashboard/sync/history/clear"},{key:"playtestReports",title:s("settings.dataHistory.playtest.title","Playtest reports"),description:s("settings.dataHistory.playtest.description","Saved automated playtest reports and logs."),metric:F(s,W(s,d.playtestReports,"settings.dataHistory.metric.reports","reports"),n.playtestReports),metricTooltip:s("settings.dataHistory.playtestReports.metric.tooltip","Number of saved playtest reports and the disk space they use."),route:"/playtest",clearEndpoint:"/api/dashboard/playtest/history/clear"},{key:"projectChanges",title:s("settings.dataHistory.projectChanges.title","Project change summary"),description:s("settings.dataHistory.projectChanges.description","Saved summaries of project changes."),metric:F(s,W(s,d.projectChanges,"settings.dataHistory.metric.records","records"),n.projectChanges),metricTooltip:s("settings.dataHistory.projectChanges.metric.tooltip","Number of saved project change summaries and the disk space they use."),route:"/changelog",clearEndpoint:"/api/dashboard/changelog/clear"},{key:"connectionLog",title:s("settings.dataHistory.connectionLog.title","Connection log"),description:s("settings.dataHistory.connectionLog.description","Saved MCP and Studio connection events."),metric:F(s,W(s,d.connectionLog,"settings.dataHistory.metric.records","records"),n.connectionLog),metricTooltip:s("settings.dataHistory.connectionLog.metric.tooltip","Number of saved connection events and the disk space they use."),route:"/connection",clearEndpoint:"/api/dashboard/connection-log/clear"}],[d,n,s]),I=async()=>{if(y){k(!0),E(null);try{if(y.kind==="uiStudio"){if(t!=="pro"||h===null)throw new Error("UI Studio place is unavailable");await K(h,{all:!0,alsoSnapshots:!0}),E(s("settings.dataHistory.uiStudio.clear.success","UI Studio saved data cleared."))}else await D.post(y.row.clearEndpoint),E(s("settings.dataHistory.clear.success","Saved data cleared."));x(null),await C()}catch{E(y.kind==="uiStudio"?s("settings.dataHistory.uiStudio.clear.failed","Failed to clear UI Studio saved data."):s("settings.dataHistory.clear.failed","Failed to clear saved data."))}finally{k(!1)}}},c=t==="pro"?h:0,i=t==="pro"&&h!==null,m=(y==null?void 0:y.kind)==="uiStudio",_=s("settings.dataHistory.title","Data & History");return e.jsxs(e.Fragment,{children:[e.jsxs("section",{id:"data-history",className:a.card,children:[e.jsxs("div",{className:a.cardHeader,children:[e.jsx(v,{label:s("settings.dataHistory.title","Data & History"),tooltip:s("settings.dataHistory.title.tooltip","Manage saved dashboard data in one place.")}),e.jsxs("div",{className:a.cardHeaderActions,children:[e.jsx(p,{text:s("settings.dataHistory.scope.tooltip","Clear actions apply to the current project and active place where applicable."),children:e.jsx("span",{className:a.headerBadge,children:N?s("common.loading","Loading"):s("settings.dataHistory.scope","Current project")})}),e.jsx(p,{text:s("settings.dataHistory.toggle.tooltip","Collapse or expand this section."),children:e.jsx("button",{className:a.collapseButton,type:"button","aria-expanded":w,"aria-controls":"settings-data-history-body","aria-label":w?s("settings.dataHistory.collapse","Collapse {title}").replace("{title}",_):s("settings.dataHistory.expand","Expand {title}").replace("{title}",_),onClick:()=>b(L=>!L),children:w?"▾":"▸"})})]})]}),w&&e.jsxs("div",{id:"settings-data-history-body",children:[e.jsx("p",{className:a.dataHistoryIntro,children:s("settings.dataHistory.intro","Review saved dashboard data, open the related page, or clear stored records from one place.")}),e.jsxs("div",{className:a.dataHistoryList,children:[B.map(L=>e.jsxs("div",{className:a.dataHistoryRow,children:[e.jsxs("div",{className:a.dataHistoryMain,children:[e.jsx("div",{className:a.dataHistoryTitle,children:L.title}),e.jsx("div",{className:a.dataHistoryDescription,children:L.description})]}),e.jsx(p,{text:L.metricTooltip,children:e.jsx("div",{className:a.dataHistoryMetric,children:L.metric})}),e.jsxs("div",{className:a.dataHistoryActions,children:[e.jsx(p,{text:s("settings.dataHistory.open.tooltip","Open the page that shows this item in detail."),children:e.jsx("a",{className:a.linkButton,href:`#${L.route}`,children:s("settings.dataHistory.open","Open")})}),e.jsx(p,{text:s("settings.dataHistory.clear.tooltip","Delete only the records saved for this item. Roblox Studio data is not changed."),children:e.jsx("button",{className:a.dangerButton,type:"button",onClick:()=>x({kind:"row",row:L}),children:s("common.clear","Clear")})})]})]},L.key)),e.jsxs("div",{className:`${a.dataHistoryRow} ${a.uiStudioDataHistoryRow}`,children:[e.jsxs("div",{className:a.dataHistoryMain,children:[e.jsx("div",{className:a.dataHistoryTitle,children:s("settings.dataHistory.uiStudio.title","UI Studio history and screenshots")}),e.jsx("div",{className:a.dataHistoryDescription,children:s("settings.dataHistory.uiStudio.description","Saved UI Studio change records, screenshots, and cleanup policy.")})]}),e.jsx(p,{text:s("settings.dataHistory.uiStudio.metric.tooltip","UI Studio change record and capture counts, plus total disk usage."),children:e.jsx("div",{className:a.dataHistoryMetric,children:us(s,o)})}),e.jsxs("div",{className:a.dataHistoryActions,children:[e.jsx(p,{text:s("settings.dataHistory.open.tooltip","Open the page that shows this item in detail."),children:e.jsx("a",{className:a.linkButton,href:"#/ui-studio?tab=history",children:s("settings.dataHistory.open","Open")})}),e.jsx(p,{text:s("settings.dataHistory.clear.tooltip","Delete only the records saved for this item. Roblox Studio data is not changed."),children:e.jsx("button",{className:a.dangerButton,type:"button",disabled:!i,onClick:()=>x({kind:"uiStudio"}),children:s("common.clear","Clear")})})]})]}),e.jsx("div",{className:`${a.dataHistoryDetail} ${a.uiStudioDataHistoryDetail}`,children:e.jsx(at,{placeId:c,tier:t,onChanged:C,embedded:!0,...t==="basic"?{sampleUsage:ee,sampleRetention:ve}:{}})})]}),S&&e.jsx("p",{className:a.inlineStatus,children:S})]})]}),e.jsx(ye,{open:y!==null,title:m?s("settings.dataHistory.uiStudio.clear.title","Clear UI Studio saved data?"):s("settings.dataHistory.clear.title","Clear saved data?"),message:m?s("settings.dataHistory.uiStudio.clear.message","This deletes saved UI Studio change records and screenshots only. Roblox Studio instances and project objects are not changed."):s("settings.dataHistory.clear.message","This deletes saved dashboard records only. Roblox Studio instances and project objects are not changed."),cancelLabel:s("common.cancel","Cancel"),confirmLabel:s("common.clear","Clear"),loading:H,onCancel:()=>!H&&x(null),onConfirm:()=>void I()})]})}const ps={en:"English",ko:"한국어",es:"Español","pt-br":"Português (BR)",ja:"日本語",id:"Bahasa Indonesia",de:"Deutsch"},hs=["debug","info","warn","error"];function ms(t){return t==="active"?a.statusActive:t==="grace"?a.statusGrace:t==="invalid"||t==="revoked"?a.statusError:a.statusInactive}function ys(t,s){return t.refreshBlockedReason==="missing_session_token"?{label:s("settings.license.status.activationRequired","Activation Required"),tooltip:s("settings.license.status.activationRequired.tooltip","Manual license activation is required before WEPPY Dashboard can refresh this status."),detail:s("settings.license.detail.missingSessionToken","Refresh is blocked because the current session token is missing."),detailTone:a.licenseNoticeWarning}:t.statusDetail==="active_cancel_pending"?{label:s("settings.license.active","Active"),tooltip:s("settings.license.status.activeCancelPending.tooltip","Cancellation is pending, but Pro access remains active until the current billing period ends."),detail:s("settings.license.detail.cancelPending","Cancellation is scheduled. Pro access remains active until the current billing period ends."),detailTone:a.licenseNoticeInfo}:t.statusDetail==="grace_provider_unavailable"?{label:s("settings.license.status.grace","Grace"),tooltip:s("settings.license.status.grace.tooltip","Provider verification is temporarily unavailable, but Pro access remains active during the grace period."),detail:s("settings.license.detail.graceProviderUnavailable","Provider unavailable. Pro access remains active during grace mode."),detailTone:a.licenseNoticeInfo}:t.statusDetail==="grace_expired"||t.statusDetail==="grace_payment_failed"?{label:s("settings.license.status.grace","Grace"),tooltip:s("settings.license.status.graceBilling.tooltip","Pro access is still available during a billing-related grace period."),detail:s("settings.license.detail.graceBilling","Pro access remains available during a billing grace period."),detailTone:a.licenseNoticeInfo}:{label:s(`settings.license.${t.status}`,t.status),tooltip:s(`settings.license.${t.status}.tooltip`,"Current license activation state."),detail:t.refreshRequired?s("settings.license.detail.refreshRecommended","License verification should be refreshed soon."):null,detailTone:a.licenseNoticeMuted}}function se({checked:t,onChange:s,testId:d,ariaLabel:j}){return e.jsxs("label",{className:a.toggleSwitch,"data-testid":d,children:[e.jsx("input",{type:"checkbox",className:a.toggleInput,checked:t,"aria-label":j,onChange:n=>s(n.target.checked)}),e.jsx("span",{className:a.toggleTrack,"aria-hidden":"true",children:e.jsx("span",{className:a.toggleThumb})})]})}function Ss(){const{t,selectedLocale:s,setLocale:d}=V(),{trackEvent:j}=pe(),{settings:n,license:l,licenseProvider:o,licenseControlsDisabled:f,licenseSubmitting:h,licenseMessage:A,activateLicense:N,refreshLicense:T,resetLicense:w,updateHotSetting:b,loading:y}=be(),[x,H]=u.useState(null),[k,S]=u.useState(""),E=l?ys(l,t):null,C=(l==null?void 0:l.tier)==="pro",B=(l==null?void 0:l.tier)==="pro"?l.maskedKey:void 0,I=(l==null?void 0:l.tier)==="pro"?"pro":"basic",c=u.useCallback(async(i,m)=>{await b(i,m),H(i),setTimeout(()=>H(_=>_===i?null:_),2e3)},[b]);return y?e.jsx("div",{className:a.page,children:e.jsx("div",{className:a.loading,children:t("common.loading")})}):e.jsxs("div",{className:a.page,children:[e.jsxs("div",{"data-testid":"settings-license-card",className:[a.card,(l==null?void 0:l.tier)==="pro"?a.licenseCardPro:""].filter(Boolean).join(" "),children:[e.jsxs("div",{className:a.cardHeader,children:[e.jsx(v,{label:t("settings.license.title","License"),tooltip:t("settings.license.title.tooltip","Current license status and subscription tier.")}),e.jsx(p,{text:f?t("settings.license.disconnected.tooltip","Reconnect to the MCP server to manage license actions from WEPPY Dashboard."):t("settings.license.live.tooltip","License actions are sent to the MCP server immediately."),children:e.jsx("span",{className:`${a.headerBadge} ${f?"":a.headerBadgeLive}`,children:f?t("settings.license.disconnected","Disconnected"):t("settings.general.liveApply","Live Apply")})})]}),e.jsxs(e.Fragment,{children:[l?e.jsxs(e.Fragment,{children:[(()=>{const i=E;return e.jsxs(e.Fragment,{children:[e.jsxs("dl",{className:a.licenseGrid,children:[e.jsx("dt",{children:e.jsx(v,{label:t("settings.license.status","Status"),tooltip:t("settings.license.status.tooltip","Current license activation state.")})}),e.jsxs("dd",{children:[e.jsx("span",{className:`${a.statusDot} ${ms(l.status)}`}),e.jsx(p,{text:(i==null?void 0:i.tooltip)??t(`settings.license.${l.status}.tooltip`,"Current license activation state."),children:(i==null?void 0:i.label)??t(`settings.license.${l.status}`,l.status)})]}),e.jsx("dt",{children:e.jsx(v,{label:t("settings.license.tier","Tier"),tooltip:t("settings.license.tier.tooltip","Current subscription tier for available WEPPY Dashboard features.")})}),e.jsx("dd",{className:l.tier==="pro"?a.proBadge:"",children:e.jsx(p,{text:t(`tier.${l.tier}.tooltip`,"Available feature set for the connected license."),children:l.tier==="pro"?t("tier.pro","Pro"):t("tier.basic","Basic")})}),B&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(v,{label:t("settings.license.key","Key"),tooltip:t("settings.license.key.tooltip","Masked license key currently loaded by the server.")})}),e.jsx("dd",{children:e.jsx(p,{text:t("settings.license.keyValue.tooltip","Masked license key currently loaded by the server."),children:B})})]}),l.provider&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(v,{label:t("settings.license.provider","Provider"),tooltip:t("settings.license.provider.tooltip","License provider used to validate this key.")})}),e.jsx("dd",{children:e.jsx(p,{text:t("settings.license.providerValue.tooltip","License provider used to validate this key."),children:l.provider})})]})]}),(i==null?void 0:i.detail)&&e.jsx("p",{className:`${a.licenseNotice} ${i.detailTone}`,children:l.refreshBlockedReason==="missing_session_token"?t("settings.license.detail.manualActivation","Manual activation required to restore Pro access."):i.detail}),l.refreshBlockedReason==="missing_session_token"&&e.jsx("p",{className:`${a.licenseNotice} ${a.licenseNoticeMuted}`,children:i==null?void 0:i.detail})]})})(),l.tier==="basic"&&e.jsx(p,{text:t("tier.upgrade.tooltip","Upgrade to Pro to unlock every feature."),children:e.jsx("a",{className:a.upgradeLink,href:"https://gum.co/u/din5in7h",target:"_blank",rel:"noopener noreferrer",onClick:()=>j("dashboard_click_event",{click_target:"upgrade_cta",placement:"settings_license",page:"settings"}),children:t("tier.upgrade")})})]}):e.jsx("div",{className:a.loading,children:t("settings.license.unavailable")}),e.jsxs("div",{className:a.licenseControls,children:[e.jsxs("div",{className:a.licenseControlRow,children:[e.jsxs("label",{className:a.licenseField,children:[e.jsx("span",{className:a.controlLabel,children:e.jsx(v,{label:t("settings.license.provider","Provider"),tooltip:t("settings.license.provider.tooltip","License provider used to validate this key.")})}),e.jsx("select",{"aria-label":t("settings.license.provider","Provider"),className:a.select,value:o,disabled:f||h,onChange:()=>{},children:e.jsx("option",{value:"gumroad",children:"gumroad"})})]}),e.jsx(p,{text:t("settings.license.refresh.tooltip","Re-fetch the current state from the license server. Useful when a billing change hasn't appeared yet."),children:e.jsx("button",{type:"button",className:a.actionBtn,disabled:f||h||!C,onClick:()=>{T()},children:h?t("common.loading"):t("settings.license.refresh","Refresh License")})}),e.jsx(p,{text:t("settings.license.reset.tooltip","Remove the currently registered license key. Use this before activating with a different key."),children:e.jsx("button",{type:"button",className:a.actionBtn,disabled:f||h||!C,onClick:()=>{w()},children:h?t("common.loading"):t("settings.license.reset","Reset License")})})]}),e.jsxs("div",{className:a.licenseControlRow,children:[e.jsxs("label",{className:`${a.licenseField} ${a.licenseFieldGrow}`,children:[e.jsx("span",{className:a.controlLabel,children:e.jsx(v,{label:t("settings.license.keyInput","License Key"),tooltip:t("settings.license.key.tooltip","Masked license key currently loaded by the server.")})}),e.jsx("input",{"aria-label":t("settings.license.keyInput","License Key"),className:a.textInput,type:"text",value:k,disabled:f||h,onChange:i=>S(i.target.value)})]}),e.jsx(p,{text:t("settings.license.activate.tooltip","Activate Pro features with the entered license key."),children:e.jsx("button",{type:"button",className:a.actionBtn,disabled:f||h,onClick:()=>{(async()=>await N(k)&&S(""))()},children:h?t("common.loading"):t("settings.license.activate","Activate License")})})]}),A&&e.jsx("p",{className:a.licenseMessage,children:A})]})]})]}),e.jsxs("div",{className:a.card,children:[e.jsxs("div",{className:a.cardHeader,children:[e.jsx(v,{label:t("settings.general.title","General Settings"),tooltip:t("settings.general.title.tooltip","Hot settings that apply immediately when changed.")}),e.jsx(p,{text:t("settings.general.liveApply.tooltip","Changes in this section are applied immediately without a separate save button."),children:e.jsx("span",{className:`${a.headerBadge} ${a.headerBadgeLive}`,children:t("settings.general.liveApply","Live Apply")})})]}),n?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:a.settingRow,children:[e.jsx("span",{className:a.settingLabel,children:e.jsx(v,{label:t("settings.general.logLevel","Log Level"),tooltip:t("settings.general.logLevel.tooltip","Sets how much detail WEPPY Dashboard writes to its logs.")})}),e.jsxs("div",{className:a.settingControl,children:[e.jsx("select",{className:a.select,value:n.hot.LOG_LEVEL,onChange:i=>c("LOG_LEVEL",i.target.value),children:hs.map(i=>e.jsx("option",{value:i,children:i},i))}),x==="LOG_LEVEL"&&e.jsx("span",{className:a.savedIndicator,children:t("settings.general.applied")})]})]}),e.jsxs("div",{className:a.settingRow,children:[e.jsx("span",{className:a.settingLabel,children:e.jsx(v,{label:t("settings.general.localHistory","Tool History Recording"),tooltip:t("settings.general.localHistory.tooltip","Stores local tool execution history for the WEPPY Dashboard history views.")})}),e.jsxs("div",{className:a.settingControl,children:[e.jsx("span",{className:`${a.savedIndicator} ${x==="ENABLE_LOCAL_HISTORY"?"":a.savedIndicatorHidden}`,children:t("settings.general.applied","Applied")}),e.jsx(se,{checked:n.hot.ENABLE_LOCAL_HISTORY,ariaLabel:t("settings.general.localHistory","Tool History Recording"),testId:"settings-toggle-enable-local-history",onChange:i=>c("ENABLE_LOCAL_HISTORY",i)})]})]}),e.jsxs("div",{className:a.settingRow,children:[e.jsx("span",{className:a.settingLabel,children:e.jsx(v,{label:t("settings.general.localStatistics","Tool Statistics Collection"),tooltip:t("settings.general.localStatistics.tooltip","Aggregates local usage statistics for WEPPY Dashboard reporting.")})}),e.jsxs("div",{className:a.settingControl,children:[e.jsx("span",{className:`${a.savedIndicator} ${x==="ENABLE_LOCAL_STATISTICS"?"":a.savedIndicatorHidden}`,children:t("settings.general.applied","Applied")}),e.jsx(se,{checked:n.hot.ENABLE_LOCAL_STATISTICS,ariaLabel:t("settings.general.localStatistics","Tool Statistics Collection"),testId:"settings-toggle-enable-local-statistics",onChange:i=>c("ENABLE_LOCAL_STATISTICS",i)})]})]}),e.jsxs("div",{className:a.settingRow,children:[e.jsx("span",{className:a.settingLabel,children:e.jsx(v,{label:t("settings.general.contextCapture","Context Capture"),tooltip:t("settings.general.contextCapture.tooltip","When enabled, WEPPY Dashboard records structured execution context for changelog and playtest views.")})}),e.jsxs("div",{className:a.settingControl,children:[e.jsx("span",{className:`${a.savedIndicator} ${x==="ENABLE_CONTEXT_CAPTURE"?"":a.savedIndicatorHidden}`,children:t("settings.general.applied","Applied")}),e.jsx(se,{checked:n.hot.ENABLE_CONTEXT_CAPTURE,ariaLabel:t("settings.general.contextCapture","Context Capture"),testId:"settings-toggle-enable-context-capture",onChange:i=>c("ENABLE_CONTEXT_CAPTURE",i)})]})]}),e.jsxs("div",{className:a.settingRow,children:[e.jsx("span",{className:a.settingLabel,children:e.jsx(v,{label:t("settings.general.requestTimeout","Action Timeout"),tooltip:t("settings.general.requestTimeout.tooltip","Maximum time WEPPY Dashboard waits for an action before it fails.")})}),e.jsxs("div",{className:a.settingControl,children:[e.jsx("input",{type:"number",className:a.numberInput,value:n.hot.REQUEST_TIMEOUT,min:1e3,max:12e4,step:1e3,onChange:i=>{const m=parseInt(i.target.value,10);isNaN(m)||c("REQUEST_TIMEOUT",m)}}),e.jsx(p,{text:t("settings.general.requestTimeout.unit.tooltip","Action timeout is measured in milliseconds."),children:e.jsx("span",{className:a.unit,children:t("settings.general.requestTimeout.unit","ms")})}),x==="REQUEST_TIMEOUT"&&e.jsx("span",{className:a.savedIndicator,children:t("settings.general.applied","Applied")})]})]})]}):e.jsx("div",{className:a.loading,children:t("settings.unavailable")})]}),e.jsx(gs,{tier:I}),e.jsxs("div",{className:a.card,children:[e.jsxs("div",{className:a.cardHeader,children:[e.jsx(v,{label:t("settings.cold.title","Server Environment"),tooltip:t("settings.cold.title.tooltip","Read-only server environment values loaded at startup.")}),e.jsx(p,{text:t("settings.readOnly.tooltip","This section shows values that cannot be edited from WEPPY Dashboard."),children:e.jsx("span",{className:a.headerBadge,children:t("settings.readOnly","Read-only")})})]}),n?e.jsxs(e.Fragment,{children:[e.jsxs("dl",{className:a.coldGrid,children:[e.jsx("dt",{children:e.jsx(v,{label:"HTTP_PORT",tooltip:t("settings.cold.httpPort.tooltip","Port number used by the MCP WEPPY Dashboard HTTP server.")})}),e.jsx("dd",{children:n.cold.HTTP_PORT}),e.jsx("dt",{children:e.jsx(v,{label:"HTTP_HOST",tooltip:t("settings.cold.httpHost.tooltip","Host interface that the MCP WEPPY Dashboard HTTP server binds to.")})}),e.jsx("dd",{children:n.cold.HTTP_HOST}),e.jsx("dt",{children:e.jsx(v,{label:"DASHBOARD_AUTO_OPEN",tooltip:t("settings.cold.dashboardAutoOpen.tooltip","Controls whether WEPPY Dashboard opens automatically in the browser when the server starts.")})}),e.jsx("dd",{children:e.jsx(p,{text:t("settings.cold.dashboardAutoOpen.value.tooltip","Current startup behavior for opening WEPPY Dashboard in a browser."),children:String(n.cold.DASHBOARD_AUTO_OPEN)})})]}),e.jsx("p",{className:a.coldHint,children:t("settings.cold.hint","Set via environment variables to change these values.")})]}):e.jsx("div",{className:a.loading,children:t("settings.unavailable")})]}),e.jsxs("div",{className:a.card,children:[e.jsx("div",{className:a.cardHeader,children:e.jsx(v,{label:t("settings.language.title","Language"),tooltip:t("settings.language.title.tooltip","Choose how the WEPPY Dashboard interface text is localized.")})}),e.jsxs("div",{className:a.langRow,children:[e.jsx("label",{children:e.jsx(v,{label:t("settings.language.dashboard","WEPPY Dashboard Language"),tooltip:t("settings.language.dashboard.tooltip","Overrides the WEPPY Dashboard language or follows the system language when set to Auto.")})}),e.jsx(p,{text:t("settings.language.auto.tooltip","Follow the operating system's language. Falls back to English when not supported."),children:e.jsxs("select",{className:a.select,value:s,onChange:i=>d(i.target.value),children:[e.jsx("option",{value:he,children:t("settings.language.auto","Auto")}),me.map(i=>e.jsx("option",{value:i,children:ps[i]??i},i))]})})]})]})]})}export{Ss as Component};
@@ -1 +1 @@
1
- import{u as o,j as s}from"./index-B-nqZCE3.js";const e="_badge_1ucqq_2",c="_dot_1ucqq_12",a="_online_1ucqq_20",l="_offline_1ucqq_25",_="_idle_1ucqq_30",u="_syncing_1ucqq_34",d="_initializing_1ucqq_35",n={badge:e,dot:c,online:a,offline:l,idle:_,syncing:u,initializing:d},g={online:"status.online",offline:"status.offline",idle:"status.idle",syncing:"status.syncing",initializing:"status.initializing"};function f({status:i}){const{t}=o();return s.jsxs("span",{className:n.badge,children:[s.jsx("span",{className:`${n.dot} ${n[i]}`}),t(g[i])]})}export{f as S};
1
+ import{u as o,j as s}from"./index-BPAvjNNu.js";const e="_badge_1ucqq_2",c="_dot_1ucqq_12",a="_online_1ucqq_20",l="_offline_1ucqq_25",_="_idle_1ucqq_30",u="_syncing_1ucqq_34",d="_initializing_1ucqq_35",n={badge:e,dot:c,online:a,offline:l,idle:_,syncing:u,initializing:d},g={online:"status.online",offline:"status.offline",idle:"status.idle",syncing:"status.syncing",initializing:"status.initializing"};function f({status:i}){const{t}=o();return s.jsxs("span",{className:n.badge,children:[s.jsx("span",{className:`${n.dot} ${n[i]}`}),t(g[i])]})}export{f as S};
@@ -1,4 +1,4 @@
1
- import{r as c,a as I,D as L,u as C,l as S,m as R,j as e,d as k,i as $,k as O,T as D,n as A}from"./index-B-nqZCE3.js";import{I as h}from"./InfoLabel-CMSu30c4.js";import{T as x}from"./TooltipText-Bnvm1FcC.js";import{C as E}from"./ConfirmModal-CM3ElkBC.js";import{S as B}from"./StatusBadge-BhRLY0yK.js";import{D as H,T as M}from"./TierComparison-CYfIb0tr.js";const F=5e3;function U(){const[t,a]=c.useState(null),[w,p]=c.useState([]),[o,y]=c.useState(!0),[u,f]=c.useState(null),m=c.useRef(null),_=c.useRef(null),r=c.useCallback(async()=>{var d;try{const[i,b]=await Promise.all([I.get("/sync/status"),I.get("/api/dashboard/place-summary")]);a(i);const j=(d=b.places)==null?void 0:d.find(N=>N.isActive);f((j==null?void 0:j.placeDirName)??null)}catch{}},[]),g=c.useCallback(async()=>{try{const d=await I.get("/sync/history",{limit:"30"});p(d.entries??[])}catch{p([])}},[]),s=c.useCallback(async()=>{await Promise.all([r(),g()]),y(!1)},[r,g]),T=c.useCallback(()=>{s()},[s]),P=c.useCallback(async()=>{await I.post("/api/dashboard/sync/history/clear"),p([]),r()},[r]);return c.useEffect(()=>(s(),_.current=setInterval(s,F),()=>{_.current&&clearInterval(_.current)}),[s]),c.useEffect(()=>{const d=new L;m.current=d,d.connect();const i=d.on("sync",()=>{r(),g()});return()=>{i(),d.disconnect(),m.current=null}},[r,g]),{status:t,history:w,loading:o,activePlaceDirName:u,refresh:T,clearHistory:P}}const W="_actions_t6ypv_66",q="_btn_t6ypv_74",G="_btnOutline_t6ypv_95",z="_btnPrimary_t6ypv_105",Y="_panel_t6ypv_115",V="_panelIcon_t6ypv_122",J="_panelTitle_t6ypv_128",Q="_panelDesc_t6ypv_137",X="_benefitList_t6ypv_145",Z="_benefitItem_t6ypv_154",l={actions:W,btn:q,btnOutline:G,btnPrimary:z,panel:Y,panelIcon:V,panelTitle:J,panelDesc:Q,benefitList:X,benefitItem:Z};function K({icon:t,title:a,description:w,benefits:p,upgradeLabel:o,upgradeHref:y}){const{t:u}=C(),[f,m]=c.useState(!1),{trackEvent:_}=S(),{pathname:r}=R(),g=r.replace(/^\//,"").split("/")[0]||"overview";return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:l.panel,children:[t&&e.jsx("div",{className:l.panelIcon,children:t}),e.jsx("div",{className:l.panelTitle,children:a}),e.jsx("div",{className:l.panelDesc,children:w}),e.jsx("ul",{className:l.benefitList,children:p.map(s=>e.jsx("li",{className:l.benefitItem,children:s},s))}),e.jsx("div",{className:l.panelDiscountWrap,children:e.jsx(H,{variant:"centered"})}),e.jsxs("div",{className:l.actions,children:[e.jsx("button",{className:`${l.btn} ${l.btnOutline}`,onClick:()=>{_("dashboard_click_event",{click_target:"tier_compare",placement:"tier_panel",page:g}),m(!0)},children:u("tier.compare","Basic vs Pro")}),e.jsx("a",{className:`${l.btn} ${l.btnPrimary}`,href:y,target:"_blank",rel:"noreferrer",onClick:()=>_("dashboard_click_event",{click_target:"upgrade_cta",placement:"tier_panel",page:g}),children:o})]})]}),f&&e.jsx(M,{onClose:()=>m(!1)})]})}const ee="_page_1warw_2",te="_card_1warw_10",se="_cardHeader_1warw_17",ne="_clearButton_1warw_29",ae="_statusRow_1warw_39",ie="_metaItem_1warw_46",ce="_statusGrid_1warw_52",oe="_table_1warw_71",re="_directionRail_1warw_99",le="_endpointLabel_1warw_105",de="_optionRail_1warw_109",pe="_directionOption_1warw_115",ye="_directionOptionActive_1warw_129",ue="_directionOptionInactive_1warw_133",_e="_direction_forward_1warw_139",he="_direction_bidirectional_1warw_143",me="_direction_reverse_1warw_147",ge="_lockBadge_1warw_152",we="_proBadge_1warw_160",fe="_forwardBadge_1warw_174",xe="_logContainer_1warw_187",be="_logEntry_1warw_194",je="_logTime_1warw_206",ve="_logType_1warw_212",Te="_logTypeWrite_1warw_221",Ne="_logTypeUpdate_1warw_225",Ie="_logTypeDelete_1warw_229",Pe="_logTypeIdle_1warw_233",Ce="_logPath_1warw_237",Le="_logEmpty_1warw_244",Se="_overlay_1warw_251",Re="_overlayTitle_1warw_261",ke="_overlayMessage_1warw_268",$e="_checklist_1warw_274",Oe="_checkItem_1warw_284",De="_upgradePanel_1warw_300",Ae="_upgradePanelHeader_1warw_307",Ee="_benefitList_1warw_315",Be="_benefitItem_1warw_324",He="_upgradeActions_1warw_339",Me="_btn_1warw_344",Fe="_btnPrimary_1warw_361",Ue="_disabled_1warw_372",n={page:ee,card:te,cardHeader:se,clearButton:ne,statusRow:ae,metaItem:ie,statusGrid:ce,table:oe,directionRail:re,endpointLabel:le,optionRail:de,directionOption:pe,directionOptionActive:ye,directionOptionInactive:ue,direction_forward:_e,direction_bidirectional:he,direction_reverse:me,lockBadge:ge,proBadge:we,forwardBadge:fe,logContainer:xe,logEntry:be,logTime:je,logType:ve,logTypeWrite:Te,logTypeUpdate:Ne,logTypeDelete:Ie,logTypeIdle:Pe,logPath:Ce,logEmpty:Le,overlay:Se,overlayTitle:Re,overlayMessage:ke,checklist:$e,checkItem:Oe,upgradePanel:De,upgradePanelHeader:Ae,benefitList:Ee,benefitItem:Be,upgradeActions:He,btn:Me,btnPrimary:Fe,disabled:Ue},We=[{key:"forward",symbol:"←"},{key:"bidirectional",symbol:"↔"},{key:"reverse",symbol:"→"}];function qe(t){const a=new Date(t);return`${String(a.getHours()).padStart(2,"0")}:${String(a.getMinutes()).padStart(2,"0")}`}function Ge(t){switch(t){case"write":return n.logTypeWrite;case"update":return n.logTypeUpdate;case"delete":return n.logTypeDelete;default:return n.logTypeIdle}}function ze(t){switch(t){case"syncing":return"syncing";case"initializing":return"initializing";case"idle":return"idle";default:return"offline"}}function Ye(t,a,w,p){const o=t(`sync.directions.cat.${a}`,a.charAt(0).toUpperCase()+a.slice(1)),y=t("sync.directions.endpoint.local","Local"),u=t("sync.directions.endpoint.studio","Studio");switch(w){case"forward":return[`${o}: ${y} <- ${u}`,t("sync.directions.tooltip.forward.body","Studio changes sync to local files only")].join(`
1
+ import{r as c,a as I,D as L,u as C,k as S,n as R,j as e,d as k,l as $,m as O,T as D,o as A}from"./index-BPAvjNNu.js";import{I as h}from"./InfoLabel-BJIFNYA5.js";import{T as x}from"./TooltipText-bSKcc3-P.js";import{C as E}from"./ConfirmModal-BDWSInRi.js";import{S as B}from"./StatusBadge-ilvVufN2.js";import{D as H,T as M}from"./TierComparison-BXMCd1IB.js";const F=5e3;function U(){const[t,a]=c.useState(null),[w,p]=c.useState([]),[o,y]=c.useState(!0),[u,f]=c.useState(null),m=c.useRef(null),_=c.useRef(null),r=c.useCallback(async()=>{var d;try{const[i,b]=await Promise.all([I.get("/sync/status"),I.get("/api/dashboard/place-summary")]);a(i);const j=(d=b.places)==null?void 0:d.find(N=>N.isActive);f((j==null?void 0:j.placeDirName)??null)}catch{}},[]),g=c.useCallback(async()=>{try{const d=await I.get("/sync/history",{limit:"30"});p(d.entries??[])}catch{p([])}},[]),s=c.useCallback(async()=>{await Promise.all([r(),g()]),y(!1)},[r,g]),T=c.useCallback(()=>{s()},[s]),P=c.useCallback(async()=>{await I.post("/api/dashboard/sync/history/clear"),p([]),r()},[r]);return c.useEffect(()=>(s(),_.current=setInterval(s,F),()=>{_.current&&clearInterval(_.current)}),[s]),c.useEffect(()=>{const d=new L;m.current=d,d.connect();const i=d.on("sync",()=>{r(),g()});return()=>{i(),d.disconnect(),m.current=null}},[r,g]),{status:t,history:w,loading:o,activePlaceDirName:u,refresh:T,clearHistory:P}}const W="_actions_t6ypv_66",q="_btn_t6ypv_74",G="_btnOutline_t6ypv_95",z="_btnPrimary_t6ypv_105",Y="_panel_t6ypv_115",V="_panelIcon_t6ypv_122",J="_panelTitle_t6ypv_128",Q="_panelDesc_t6ypv_137",X="_benefitList_t6ypv_145",Z="_benefitItem_t6ypv_154",l={actions:W,btn:q,btnOutline:G,btnPrimary:z,panel:Y,panelIcon:V,panelTitle:J,panelDesc:Q,benefitList:X,benefitItem:Z};function K({icon:t,title:a,description:w,benefits:p,upgradeLabel:o,upgradeHref:y}){const{t:u}=C(),[f,m]=c.useState(!1),{trackEvent:_}=S(),{pathname:r}=R(),g=r.replace(/^\//,"").split("/")[0]||"overview";return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:l.panel,children:[t&&e.jsx("div",{className:l.panelIcon,children:t}),e.jsx("div",{className:l.panelTitle,children:a}),e.jsx("div",{className:l.panelDesc,children:w}),e.jsx("ul",{className:l.benefitList,children:p.map(s=>e.jsx("li",{className:l.benefitItem,children:s},s))}),e.jsx("div",{className:l.panelDiscountWrap,children:e.jsx(H,{variant:"centered"})}),e.jsxs("div",{className:l.actions,children:[e.jsx("button",{className:`${l.btn} ${l.btnOutline}`,onClick:()=>{_("dashboard_click_event",{click_target:"tier_compare",placement:"tier_panel",page:g}),m(!0)},children:u("tier.compare","Basic vs Pro")}),e.jsx("a",{className:`${l.btn} ${l.btnPrimary}`,href:y,target:"_blank",rel:"noreferrer",onClick:()=>_("dashboard_click_event",{click_target:"upgrade_cta",placement:"tier_panel",page:g}),children:o})]})]}),f&&e.jsx(M,{onClose:()=>m(!1)})]})}const ee="_page_1warw_2",te="_card_1warw_10",se="_cardHeader_1warw_17",ne="_clearButton_1warw_29",ae="_statusRow_1warw_39",ie="_metaItem_1warw_46",ce="_statusGrid_1warw_52",oe="_table_1warw_71",re="_directionRail_1warw_99",le="_endpointLabel_1warw_105",de="_optionRail_1warw_109",pe="_directionOption_1warw_115",ye="_directionOptionActive_1warw_129",ue="_directionOptionInactive_1warw_133",_e="_direction_forward_1warw_139",he="_direction_bidirectional_1warw_143",me="_direction_reverse_1warw_147",ge="_lockBadge_1warw_152",we="_proBadge_1warw_160",fe="_forwardBadge_1warw_174",xe="_logContainer_1warw_187",be="_logEntry_1warw_194",je="_logTime_1warw_206",ve="_logType_1warw_212",Te="_logTypeWrite_1warw_221",Ne="_logTypeUpdate_1warw_225",Ie="_logTypeDelete_1warw_229",Pe="_logTypeIdle_1warw_233",Ce="_logPath_1warw_237",Le="_logEmpty_1warw_244",Se="_overlay_1warw_251",Re="_overlayTitle_1warw_261",ke="_overlayMessage_1warw_268",$e="_checklist_1warw_274",Oe="_checkItem_1warw_284",De="_upgradePanel_1warw_300",Ae="_upgradePanelHeader_1warw_307",Ee="_benefitList_1warw_315",Be="_benefitItem_1warw_324",He="_upgradeActions_1warw_339",Me="_btn_1warw_344",Fe="_btnPrimary_1warw_361",Ue="_disabled_1warw_372",n={page:ee,card:te,cardHeader:se,clearButton:ne,statusRow:ae,metaItem:ie,statusGrid:ce,table:oe,directionRail:re,endpointLabel:le,optionRail:de,directionOption:pe,directionOptionActive:ye,directionOptionInactive:ue,direction_forward:_e,direction_bidirectional:he,direction_reverse:me,lockBadge:ge,proBadge:we,forwardBadge:fe,logContainer:xe,logEntry:be,logTime:je,logType:ve,logTypeWrite:Te,logTypeUpdate:Ne,logTypeDelete:Ie,logTypeIdle:Pe,logPath:Ce,logEmpty:Le,overlay:Se,overlayTitle:Re,overlayMessage:ke,checklist:$e,checkItem:Oe,upgradePanel:De,upgradePanelHeader:Ae,benefitList:Ee,benefitItem:Be,upgradeActions:He,btn:Me,btnPrimary:Fe,disabled:Ue},We=[{key:"forward",symbol:"←"},{key:"bidirectional",symbol:"↔"},{key:"reverse",symbol:"→"}];function qe(t){const a=new Date(t);return`${String(a.getHours()).padStart(2,"0")}:${String(a.getMinutes()).padStart(2,"0")}`}function Ge(t){switch(t){case"write":return n.logTypeWrite;case"update":return n.logTypeUpdate;case"delete":return n.logTypeDelete;default:return n.logTypeIdle}}function ze(t){switch(t){case"syncing":return"syncing";case"initializing":return"initializing";case"idle":return"idle";default:return"offline"}}function Ye(t,a,w,p){const o=t(`sync.directions.cat.${a}`,a.charAt(0).toUpperCase()+a.slice(1)),y=t("sync.directions.endpoint.local","Local"),u=t("sync.directions.endpoint.studio","Studio");switch(w){case"forward":return[`${o}: ${y} <- ${u}`,t("sync.directions.tooltip.forward.body","Studio changes sync to local files only")].join(`
2
2
  `);case"bidirectional":return[`${o}: ${y} <-> ${u}`,t("sync.directions.tooltip.bidirectional.body","Two-way sync between Local and Studio"),p?t("sync.directions.tooltip.proRequired","Pro required in Basic tier"):""].filter(Boolean).join(`
3
3
  `);case"reverse":return[`${o}: ${y} -> ${u}`,t("sync.directions.tooltip.reverse.body","Push local file changes to Studio"),p?t("sync.directions.tooltip.proRequired","Pro required in Basic tier"):""].filter(Boolean).join(`
4
4
  `);default:return o}}const Ve=["scripts","values","containers","data","services"];function Je(t,a){return a==="manual"?t("sync.directions.mode.manual","Manual"):a==="auto"?t("sync.directions.mode.auto","Auto"):"-"}function Qe(t,a){return a==="manual"?t("sync.directions.mode.manual.tooltip","Applies sync changes only when you trigger them manually."):a==="auto"?t("sync.directions.mode.auto.tooltip","Applies sync changes automatically when updates arrive."):""}function Xe(t,a){switch(a){case"write":return t("sync.log.type.write","WRITE");case"update":return t("sync.log.type.update","UPDATE");case"delete":return t("sync.log.type.delete","DELETE");default:return t("sync.log.type.idle","IDLE")}}function Ze(t,a){switch(a){case"write":return t("sync.log.type.write.tooltip","A new sync output was written to disk.");case"update":return t("sync.log.type.update.tooltip","An existing synced file or instance was updated.");case"delete":return t("sync.log.type.delete.tooltip","A synced file or instance was removed.");default:return t("sync.log.type.idle.tooltip","A sync event was recorded without a file mutation.")}}function it(){const{t}=C(),{level:a}=k(),{tier:w,loading:p}=$(),o=U(),{show:y}=O(),[u,f]=c.useState(!1),[m,_]=c.useState(!1),r=!p&&w==="basic";if(a==="disconnected"||a==="serverOnly")return e.jsx("div",{className:n.page,children:e.jsx("div",{className:n.card,children:e.jsxs("div",{className:n.overlay,children:[e.jsx("div",{className:n.overlayTitle,children:t("sync.overlay.title","Roblox Studio plugin required")}),e.jsx("div",{className:n.overlayMessage,children:t("sync.overlay.message","Sync status will be available once the Roblox Studio plugin connects.")}),e.jsxs("ul",{className:n.checklist,children:[e.jsx("li",{className:n.checkItem,children:t("sync.overlay.check1","Is Roblox Studio running?")}),e.jsx("li",{className:n.checkItem,children:t("sync.overlay.check2","Is the WEPPY Plugin installed?")})]})]})})});const s=o.status,T=o.history,P=ze(s==null?void 0:s.state),d=async()=>{_(!0);try{await o.clearHistory(),y(t("toast.clearSuccess","Cleared successfully"),"success"),f(!1)}catch{y(t("toast.clearFailed","Failed to clear data"),"error")}finally{_(!1)}};return e.jsxs("div",{className:n.page,children:[e.jsxs("div",{className:n.card,children:[e.jsxs("div",{className:n.cardHeader,children:[e.jsx(x,{text:t("sync.status.title.tooltip","Current Studio and local file sync status for this place."),children:t("sync.status.title","Sync Status")}),r&&e.jsx(x,{text:t("sync.status.forwardOnly.tooltip","Basic tier allows Studio to local forward sync only."),children:e.jsx("span",{className:n.forwardBadge,children:t("sync.status.forwardOnly","Forward Only")})})]}),e.jsxs("div",{className:n.statusRow,children:[e.jsx(B,{status:P}),(s==null?void 0:s.placeName)&&e.jsxs("span",{className:n.metaItem,children:[e.jsx(h,{label:t("sync.status.place","Place"),tooltip:t("sync.status.place.tooltip","Connected Roblox place name and place ID.")}),": ",s.placeName,s.placeId?` (${s.placeId})`:""]})]}),e.jsxs("dl",{className:n.statusGrid,children:[(s==null?void 0:s.syncRoot)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(h,{label:t("sync.status.path","Path"),tooltip:t("sync.status.path.tooltip","Local filesystem root currently used for sync output.")})}),e.jsx("dd",{children:s.syncRoot})]}),o.activePlaceDirName&&(s==null?void 0:s.syncRoot)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(h,{label:t("sync.status.placePath","Place Path"),tooltip:t("sync.status.placePath.tooltip","Active place directory where explorer files are synced.")})}),e.jsx("dd",{children:`${s.syncRoot}/${o.activePlaceDirName}/explorer`})]}),(s==null?void 0:s.instanceCount)!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(h,{label:t("sync.status.instances","Instances"),tooltip:t("sync.status.instances.tooltip","Total synced Roblox instances tracked in the local mirror.")})}),e.jsx("dd",{children:s.instanceCount})]}),(s==null?void 0:s.scriptCount)!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(h,{label:t("sync.status.scripts","Scripts"),tooltip:t("sync.status.scripts.tooltip","Total synced script files currently indexed for this place.")})}),e.jsx("dd",{children:s.scriptCount})]}),(s==null?void 0:s.state)==="syncing"&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(h,{label:t("sync.status.state","State"),tooltip:t("sync.status.state.tooltip","Current runtime sync state reported by the server.")})}),e.jsx("dd",{children:t("status.syncing","Syncing")})]})]})]}),(s==null?void 0:s.directions)&&e.jsxs("div",{className:n.card,children:[e.jsx("div",{className:n.cardHeader,children:e.jsx(x,{text:t("sync.directions.title.tooltip","Per-category sync direction and apply behavior between Local and Studio."),children:t("sync.directions.title","Sync Directions")})}),e.jsxs("table",{className:n.table,children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:e.jsx(h,{label:t("sync.directions.type","Type"),tooltip:t("sync.directions.type.tooltip","Sync category affected by this rule.")})}),e.jsx("th",{children:e.jsx(h,{label:t("sync.directions.direction","Direction"),tooltip:t("sync.directions.direction.tooltip","Whether each category syncs from Studio, to Studio, or both ways.")})}),e.jsx("th",{children:e.jsx(h,{label:t("sync.directions.applyMode","Apply Mode"),tooltip:t("sync.directions.applyMode.tooltip","How incoming sync changes are applied for this category.")})})]})}),e.jsx("tbody",{children:Ve.map(i=>{var N;const b=s.directions[i],j=(N=s.applyModes)==null?void 0:N[i];return e.jsxs("tr",{children:[e.jsx("td",{children:t(`sync.directions.cat.${i}`,i.charAt(0).toUpperCase()+i.slice(1))}),e.jsx("td",{children:e.jsxs("div",{className:n.directionRail,"aria-label":`${i}-direction-rail`,children:[e.jsx(x,{text:t("sync.directions.endpoint.local.tooltip","Local files on disk are always shown on the left side of the direction rail."),children:e.jsx("span",{className:n.endpointLabel,children:t("sync.directions.endpoint.local","Local")})}),e.jsx("span",{className:n.optionRail,children:We.map(v=>e.jsx(D,{text:Ye(t,i,v.key,r),children:e.jsx("span",{className:`${n.directionOption} ${b===v.key?n.directionOptionActive:n.directionOptionInactive} ${n[`direction_${v.key}`]??""}`,"data-active":b===v.key?"true":"false",children:v.symbol})},v.key))}),e.jsx(x,{text:t("sync.directions.endpoint.studio.tooltip","Roblox Studio is always shown on the right side of the direction rail."),children:e.jsx("span",{className:n.endpointLabel,children:t("sync.directions.endpoint.studio","Studio")})})]})}),e.jsx("td",{children:e.jsx(x,{text:Qe(t,j),children:Je(t,j)})})]},i)})})]})]}),e.jsxs("div",{className:n.card,children:[e.jsxs("div",{className:n.cardHeader,children:[e.jsx("span",{children:t("sync.log.title","Sync Log")}),e.jsx("button",{className:n.clearButton,onClick:()=>f(!0),children:t("common.clear","Clear")})]}),e.jsx("div",{className:n.logContainer,children:T.length===0?e.jsx("div",{className:n.logEmpty,children:t("sync.log.empty","No sync events yet")}):T.map((i,b)=>e.jsxs("div",{className:n.logEntry,children:[e.jsx("span",{className:n.logTime,children:qe(i.timestamp)}),e.jsx(x,{text:Ze(t,i.type),children:e.jsx("span",{className:`${n.logType} ${Ge(i.type)}`,children:Xe(t,i.type)})}),e.jsxs("span",{className:n.logPath,children:[i.path,i.details?` — ${i.details}`:""]})]},b))})]}),r&&e.jsx(K,{title:t("sync.upgrade.title","Unlock Full Sync with Pro"),description:t("tier.banner.save","Save AI tokens with Pro!"),benefits:[t("sync.upgrade.benefit1","Bidirectional sync — edit files, auto-apply to Studio"),t("sync.upgrade.benefit2","Reverse sync — push file changes back to Studio"),t("sync.upgrade.benefit3","Full sync history and detailed change log")],upgradeLabel:t("sync.upgrade.buy","Upgrade to Pro"),upgradeHref:A.sync}),e.jsx(E,{open:u,title:t("sync.clear.title","Clear sync log?"),message:t("sync.clear.message","This permanently removes the stored sync log for the current place."),cancelLabel:t("common.cancel","Cancel"),confirmLabel:t("common.clear","Clear"),loading:m,onCancel:()=>!m&&f(!1),onConfirm:d})]})}export{it as Component};
@@ -0,0 +1 @@
1
+ ._tabBar_1o4kh_2{display:flex;align-items:stretch;gap:2px;border-bottom:1px solid var(--border)}._tabs_1o4kh_9{display:flex;gap:2px}._actions_1o4kh_14{margin-left:auto;display:flex;align-items:center;gap:8px;padding-bottom:4px}._tab_1o4kh_2{font-family:var(--font-label);font-size:12px;font-weight:500;padding:8px 16px;background:none;border:none;border-bottom:2px solid transparent;color:var(--text-secondary);cursor:pointer;transition:color var(--transition),border-color var(--transition)}._tab_1o4kh_2:hover{color:var(--text-primary)}._tabActive_1o4kh_39{color:var(--accent);border-bottom-color:var(--accent)}