@weppy/roblox-mcp 2.0.7 → 2.0.9

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 (171) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +19 -1
  3. package/COMMERCIAL-LICENSE.md +1 -1
  4. package/README.md +12 -12
  5. package/TRADEMARKS.md +1 -1
  6. package/docs/assets/screenshots/plugin_main.png +0 -0
  7. package/docs/assets/screenshots/plugins_menu.png +0 -0
  8. package/docs/assets/screenshots/weppy_plugin_toolbar.png +0 -0
  9. package/docs/en/dashboard/changelog.md +1 -1
  10. package/docs/en/dashboard/connection.md +1 -1
  11. package/docs/en/dashboard/overview.md +1 -1
  12. package/docs/en/dashboard/playtest.md +1 -1
  13. package/docs/en/dashboard/settings.md +1 -1
  14. package/docs/en/dashboard/sync.md +1 -1
  15. package/docs/en/dashboard/tools.md +1 -1
  16. package/docs/en/installation/README.md +5 -3
  17. package/docs/en/installation/ai-apps/antigravity.md +1 -1
  18. package/docs/en/installation/ai-apps/claude-app.md +1 -1
  19. package/docs/en/installation/ai-apps/claude-code.md +1 -1
  20. package/docs/en/installation/ai-apps/codex-app.md +1 -1
  21. package/docs/en/installation/ai-apps/codex-cli.md +1 -1
  22. package/docs/en/installation/ai-apps/cursor.md +1 -1
  23. package/docs/en/installation/ai-apps/gemini-cli.md +1 -1
  24. package/docs/en/installation/roblox-explorer.md +9 -9
  25. package/docs/en/installation/roblox-plugin.md +3 -3
  26. package/docs/en/pro-upgrade.md +3 -3
  27. package/docs/en/sync/overview.md +2 -2
  28. package/docs/en/tools/system-and-debugging.md +8 -0
  29. package/docs/es/README.md +7 -7
  30. package/docs/es/dashboard/changelog.md +1 -1
  31. package/docs/es/dashboard/connection.md +1 -1
  32. package/docs/es/dashboard/overview.md +1 -1
  33. package/docs/es/dashboard/playtest.md +1 -1
  34. package/docs/es/dashboard/settings.md +1 -1
  35. package/docs/es/dashboard/sync.md +1 -1
  36. package/docs/es/dashboard/tools.md +1 -1
  37. package/docs/es/installation/README.md +2 -2
  38. package/docs/es/installation/ai-apps/antigravity.md +1 -1
  39. package/docs/es/installation/ai-apps/claude-app.md +1 -1
  40. package/docs/es/installation/ai-apps/claude-code.md +1 -1
  41. package/docs/es/installation/ai-apps/codex-app.md +1 -1
  42. package/docs/es/installation/ai-apps/codex-cli.md +1 -1
  43. package/docs/es/installation/ai-apps/cursor.md +1 -1
  44. package/docs/es/installation/ai-apps/gemini-cli.md +1 -1
  45. package/docs/es/installation/roblox-explorer.md +9 -9
  46. package/docs/es/installation/roblox-plugin.md +3 -3
  47. package/docs/es/pro-upgrade.md +1 -1
  48. package/docs/es/sync/overview.md +2 -2
  49. package/docs/es/tools/system-and-debugging.md +8 -0
  50. package/docs/id/README.md +7 -7
  51. package/docs/id/dashboard/changelog.md +1 -1
  52. package/docs/id/dashboard/connection.md +1 -1
  53. package/docs/id/dashboard/overview.md +1 -1
  54. package/docs/id/dashboard/playtest.md +1 -1
  55. package/docs/id/dashboard/settings.md +1 -1
  56. package/docs/id/dashboard/sync.md +1 -1
  57. package/docs/id/dashboard/tools.md +1 -1
  58. package/docs/id/installation/README.md +3 -3
  59. package/docs/id/installation/ai-apps/antigravity.md +1 -1
  60. package/docs/id/installation/ai-apps/claude-app.md +1 -1
  61. package/docs/id/installation/ai-apps/claude-code.md +1 -1
  62. package/docs/id/installation/ai-apps/codex-app.md +1 -1
  63. package/docs/id/installation/ai-apps/codex-cli.md +1 -1
  64. package/docs/id/installation/ai-apps/cursor.md +1 -1
  65. package/docs/id/installation/ai-apps/gemini-cli.md +1 -1
  66. package/docs/id/installation/roblox-explorer.md +9 -9
  67. package/docs/id/installation/roblox-plugin.md +3 -3
  68. package/docs/id/pro-upgrade.md +1 -1
  69. package/docs/id/sync/overview.md +2 -2
  70. package/docs/id/tools/system-and-debugging.md +8 -0
  71. package/docs/ja/README.md +7 -7
  72. package/docs/ja/installation/README.md +3 -3
  73. package/docs/ja/installation/ai-apps/antigravity.md +1 -1
  74. package/docs/ja/installation/ai-apps/claude-app.md +1 -1
  75. package/docs/ja/installation/ai-apps/claude-code.md +1 -1
  76. package/docs/ja/installation/ai-apps/codex-app.md +1 -1
  77. package/docs/ja/installation/ai-apps/codex-cli.md +1 -1
  78. package/docs/ja/installation/ai-apps/cursor.md +1 -1
  79. package/docs/ja/installation/ai-apps/gemini-cli.md +1 -1
  80. package/docs/ja/installation/roblox-explorer.md +9 -9
  81. package/docs/ja/installation/roblox-plugin.md +3 -3
  82. package/docs/ja/pro-upgrade.md +1 -1
  83. package/docs/ja/sync/overview.md +2 -2
  84. package/docs/ja/tools/system-and-debugging.md +8 -0
  85. package/docs/ko/README.md +7 -7
  86. package/docs/ko/installation/README.md +5 -3
  87. package/docs/ko/installation/ai-apps/antigravity.md +1 -1
  88. package/docs/ko/installation/ai-apps/claude-app.md +1 -1
  89. package/docs/ko/installation/ai-apps/claude-code.md +1 -1
  90. package/docs/ko/installation/ai-apps/codex-app.md +1 -1
  91. package/docs/ko/installation/ai-apps/codex-cli.md +1 -1
  92. package/docs/ko/installation/ai-apps/cursor.md +1 -1
  93. package/docs/ko/installation/ai-apps/gemini-cli.md +1 -1
  94. package/docs/ko/installation/roblox-explorer.md +9 -9
  95. package/docs/ko/installation/roblox-plugin.md +3 -3
  96. package/docs/ko/pro-upgrade.md +1 -1
  97. package/docs/ko/sync/overview.md +2 -2
  98. package/docs/ko/tools/system-and-debugging.md +8 -0
  99. package/docs/pt-br/README.md +8 -8
  100. package/docs/pt-br/dashboard/changelog.md +1 -1
  101. package/docs/pt-br/dashboard/connection.md +1 -1
  102. package/docs/pt-br/dashboard/overview.md +1 -1
  103. package/docs/pt-br/dashboard/playtest.md +1 -1
  104. package/docs/pt-br/dashboard/settings.md +1 -1
  105. package/docs/pt-br/dashboard/sync.md +1 -1
  106. package/docs/pt-br/dashboard/tools.md +1 -1
  107. package/docs/pt-br/installation/README.md +3 -3
  108. package/docs/pt-br/installation/ai-apps/antigravity.md +1 -1
  109. package/docs/pt-br/installation/ai-apps/claude-app.md +1 -1
  110. package/docs/pt-br/installation/ai-apps/claude-code.md +1 -1
  111. package/docs/pt-br/installation/ai-apps/codex-app.md +1 -1
  112. package/docs/pt-br/installation/ai-apps/codex-cli.md +1 -1
  113. package/docs/pt-br/installation/ai-apps/cursor.md +1 -1
  114. package/docs/pt-br/installation/ai-apps/gemini-cli.md +1 -1
  115. package/docs/pt-br/installation/roblox-explorer.md +9 -9
  116. package/docs/pt-br/installation/roblox-plugin.md +3 -3
  117. package/docs/pt-br/pro-upgrade.md +1 -1
  118. package/docs/pt-br/sync/overview.md +2 -2
  119. package/docs/pt-br/tools/system-and-debugging.md +8 -0
  120. package/docs/troubleshooting.md +1 -1
  121. package/install.ps1 +37 -14
  122. package/install.sh +38 -3
  123. package/llms-full.txt +8 -8
  124. package/llms.txt +5 -5
  125. package/package.json +1 -1
  126. package/plugins/weppy-roblox-mcp/.claude-plugin/plugin.json +1 -1
  127. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogDetailPage-D6Tqz7ut.css +1 -0
  128. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogDetailPage-DRPIGDB0.js +1 -0
  129. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogPage-BH87M2hn.css +1 -0
  130. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogPage-DVPYTw2L.js +1 -0
  131. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ConfirmModal-CvXLNYq0.js → ConfirmModal-Db4rfrTo.js} +1 -1
  132. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ConnectionPage-Cv2i3LSr.js +1 -0
  133. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{InfoLabel-vz7vtbbV.js → InfoLabel-DzXzzs6Q.js} +1 -1
  134. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/OverviewPage-Dsfl-NRT.css +1 -0
  135. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/OverviewPage-FoC28UL8.js +1 -0
  136. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/PlaytestPage-BjBAsHLz.js +11 -0
  137. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/PlaytestPage-Dw8nj399.css +1 -0
  138. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{PropertyDiff-CbDafceC.js → PropertyDiff-BZMdMzMr.js} +1 -1
  139. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SettingsPage-BB7-WAMU.css +1 -0
  140. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SettingsPage-BKp2VKMW.js +1 -0
  141. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{StatusBadge-BMTgkxDJ.js → StatusBadge-DtcYlxe-.js} +1 -1
  142. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SyncPage-DcELF5_j.js +4 -0
  143. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromo-CcQarFkP.css +1 -0
  144. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromo.module-BBX3CVXn.js +1 -0
  145. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromoProgress-r5fgmYI5.js +1 -0
  146. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ToolsPage-Cfau3bX3.js +1 -0
  147. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/index-DWRH2iF4.js +129 -0
  148. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{tier-promo-config-CJ-J0n2q.css → tier-promo-config-C-Xy3iYW.css} +1 -1
  149. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{tier-promo-config-B9lIKWCQ.js → tier-promo-config-CQFDWwo4.js} +1 -1
  150. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{useLiveUptime-DXXyWm6j.js → useLiveUptime-5lD1XKnw.js} +1 -1
  151. package/plugins/weppy-roblox-mcp/dashboard/dist/index.html +3 -3
  152. package/plugins/weppy-roblox-mcp/dashboard/dist/wrox-icon.png +0 -0
  153. package/plugins/weppy-roblox-mcp/dist/index.js +79 -76
  154. package/plugins/weppy-roblox-mcp/roblox-plugin/WeppyRobloxMCP.rbxm +0 -0
  155. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogDetailPage-C2oKsYGC.css +0 -1
  156. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogDetailPage-IgHLnaEX.js +0 -1
  157. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogPage-Br-A5H5t.css +0 -1
  158. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogPage-Dao4jPQA.js +0 -1
  159. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ConnectionPage-Bl7tLgL2.js +0 -1
  160. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/OverviewPage-BDDctbAl.js +0 -1
  161. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/OverviewPage-CS05LsEh.css +0 -1
  162. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/PlaytestPage-C0iCoAQp.js +0 -1
  163. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/PlaytestPage-LnuHE5FL.css +0 -1
  164. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SettingsPage-CJs9ctOf.js +0 -1
  165. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SettingsPage-DP9OFhNb.css +0 -1
  166. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SyncPage-BfXIBNVS.js +0 -4
  167. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromoPanel-CUrTMsXB.js +0 -1
  168. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromoProgress-DBA-FZGE.js +0 -1
  169. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ToolsPage-O4dXhEU-.js +0 -1
  170. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/index-CkXvRg-O.js +0 -69
  171. package/smithery.yaml +0 -13
@@ -74,6 +74,14 @@ Use `batch_execute` para agrupar varios comandos em uma unica solicitacao.
74
74
  | `remove` | Remover itens da selecao | Pro |
75
75
  | `watch` | Monitorar mudancas de selecao | Pro |
76
76
 
77
+ ### Manage Context (Basic)
78
+
79
+ | Acao | Descricao | Tier |
80
+ |------|-----------|------|
81
+ | `begin` | Inicia um contexto de execucao estruturado para o escopo atual de sessao/place | Basic |
82
+ | `update` | Atualiza a intencao, as areas afetadas ou os metadados de replay do contexto ativo | Basic |
83
+ | `end` | Encerra o contexto de execucao ativo e persiste o snapshot final | Basic |
84
+
77
85
  ### Batch Execute (Pro)
78
86
 
79
87
  Executa varios comandos em um unico lote. Cada comando inclui nome da tool e argumentos, roda em ordem e pode continuar apos erros se configurado.
@@ -5,7 +5,7 @@
5
5
  **Symptom:** "Connection failed" or plugin shows disconnected in Roblox Studio.
6
6
 
7
7
  1. Make sure the MCP server is running: `npx -y @weppy/roblox-mcp`
8
- 2. In Roblox Studio: Plugins tab → W-MCP → Connect
8
+ 2. In Roblox Studio: Plugins tab → WROX → Connect
9
9
  3. Confirm nothing is blocking `localhost:3002` (firewall, antivirus, VPN)
10
10
  4. Try restarting both Roblox Studio and the MCP server
11
11
 
package/install.ps1 CHANGED
@@ -1,5 +1,5 @@
1
1
  #
2
- # Weppy Roblox MCP — One-line install script (Windows PowerShell)
2
+ # WROX — One-line install script (Windows PowerShell)
3
3
  #
4
4
  # Usage:
5
5
  # irm https://raw.githubusercontent.com/hope1026/weppy-roblox-mcp/main/install.ps1 | iex
@@ -11,6 +11,8 @@
11
11
  #
12
12
 
13
13
  $ErrorActionPreference = "Stop"
14
+ $script:InstallLogPath = Join-Path ([System.IO.Path]::GetTempPath()) ("wrox-install-{0:yyyyMMdd-HHmmss}.log" -f (Get-Date))
15
+ $script:TranscriptStarted = $false
14
16
 
15
17
  # ── Utilities ──
16
18
  function Write-Step($step, $msg) { Write-Host "`n[$step] $msg" -ForegroundColor Cyan -NoNewline; Write-Host "" }
@@ -18,6 +20,32 @@ function Write-Ok($msg) { Write-Host " ✓ $msg" -ForegroundColor Green }
18
20
  function Write-Warn($msg) { Write-Host " ⚠ $msg" -ForegroundColor Yellow }
19
21
  function Write-Fail($msg) { Write-Host " ✗ $msg" -ForegroundColor Red }
20
22
  function Write-Info($msg) { Write-Host " [INFO] $msg" -ForegroundColor Blue }
23
+ function Stop-InstallTranscript() {
24
+ if ($script:TranscriptStarted) {
25
+ try { Stop-Transcript | Out-Null } catch {}
26
+ $script:TranscriptStarted = $false
27
+ }
28
+ }
29
+ function Pause-OnFailureIfInteractive() {
30
+ if ($Host.Name -match 'ConsoleHost|Visual Studio Code Host') {
31
+ try { Read-Host "Press Enter to exit" | Out-Null } catch {}
32
+ }
33
+ }
34
+ function Abort-Install($msg) { throw $msg }
35
+
36
+ try {
37
+ Start-Transcript -Path $script:InstallLogPath -Force | Out-Null
38
+ $script:TranscriptStarted = $true
39
+ } catch {}
40
+
41
+ trap {
42
+ $message = if ($_.Exception) { $_.Exception.Message } else { $_.ToString() }
43
+ Write-Fail "Installation failed: $message"
44
+ Write-Host " Log saved to: $script:InstallLogPath" -ForegroundColor Yellow
45
+ Pause-OnFailureIfInteractive
46
+ Stop-InstallTranscript
47
+ exit 1
48
+ }
21
49
 
22
50
  function Confirm-Action($prompt) {
23
51
  $reply = Read-Host "$prompt (Y/n)"
@@ -52,7 +80,7 @@ function Test-LfsPointer($filePath) {
52
80
 
53
81
  # ── Header ──
54
82
  Write-Host ""
55
- Write-Host "Weppy Roblox MCP Installer" -ForegroundColor White -BackgroundColor DarkCyan
83
+ Write-Host "WROX Installer" -ForegroundColor White -BackgroundColor DarkCyan
56
84
  Write-Host "AI-powered Roblox Studio integration" -ForegroundColor DarkGray
57
85
  Write-Host ("=" * 40)
58
86
 
@@ -61,16 +89,12 @@ try {
61
89
  $nodeVersion = (node -v) -replace 'v', ''
62
90
  $majorVersion = [int]($nodeVersion.Split('.')[0])
63
91
  if ($majorVersion -lt 18) {
64
- Write-Fail "Node.js 18 or higher required (current: v$nodeVersion)"
65
- Write-Host " Upgrade: https://nodejs.org"
66
- exit 1
92
+ Abort-Install "Node.js 18 or higher required (current: v$nodeVersion). Upgrade: https://nodejs.org"
67
93
  }
68
94
  Write-Ok "Node.js v$nodeVersion detected"
69
95
  }
70
96
  catch {
71
- Write-Fail "Node.js is not installed"
72
- Write-Host " Install Node.js 18+: https://nodejs.org"
73
- exit 1
97
+ Abort-Install "Node.js is not installed. Install Node.js 18+: https://nodejs.org"
74
98
  }
75
99
 
76
100
  # ═══════════════════════════════════
@@ -84,8 +108,7 @@ if (Confirm-Action " Run npm install -g @weppy/roblox-mcp?") {
84
108
  Write-Ok "Installed @weppy/roblox-mcp"
85
109
  }
86
110
  catch {
87
- Write-Fail "npm install failed: $_"
88
- exit 1
111
+ Abort-Install "npm install failed: $_"
89
112
  }
90
113
  }
91
114
  else {
@@ -116,9 +139,7 @@ foreach ($p in $searchPaths) {
116
139
 
117
140
  if ($bundledPlugin) {
118
141
  if (Test-LfsPointer $bundledPlugin) {
119
- Write-Fail "Bundled plugin payload is invalid (Git LFS pointer detected)"
120
- Write-Info "Install the plugin from the GitHub release ZIP instead"
121
- exit 1
142
+ Abort-Install "Bundled plugin payload is invalid (Git LFS pointer detected). Install the plugin from the GitHub release ZIP instead."
122
143
  }
123
144
 
124
145
  Write-Host " → $pluginsDir\$pluginName"
@@ -283,7 +304,7 @@ Write-Host "Installation complete!" -ForegroundColor Green
283
304
  Write-Host ""
284
305
  Write-Host " Next steps:"
285
306
  Write-Host " 1. Restart Roblox Studio"
286
- Write-Host " 2. Look for the W-MCP button in the Plugins tab"
307
+ Write-Host " 2. Look for the WROX button in the Plugins tab"
287
308
  Write-Host " 3. Click Connect and start building with AI!"
288
309
  Write-Host ""
289
310
  Write-Host " Auto registration: Claude Code, Claude Desktop, Cursor, Codex CLI, Gemini CLI"
@@ -291,3 +312,5 @@ Write-Host " Manual setup required: Codex App, Antigravity"
291
312
  Write-Host ""
292
313
  Write-Host " Docs: https://github.com/hope1026/weppy-roblox-mcp" -ForegroundColor DarkGray
293
314
  Write-Host ""
315
+
316
+ Stop-InstallTranscript
package/install.sh CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bash
2
2
  #
3
- # Weppy Roblox MCP — One-line install script (macOS/Linux)
3
+ # WROX — One-line install script (macOS/Linux)
4
4
  #
5
5
  # Usage:
6
6
  # curl -fsSL https://raw.githubusercontent.com/hope1026/weppy-roblox-mcp/main/install.sh | bash
@@ -23,6 +23,16 @@ DIM='\033[2m'
23
23
  BOLD='\033[1m'
24
24
  NC='\033[0m'
25
25
 
26
+ INSTALL_LOG_FILE="$(mktemp "${TMPDIR:-/tmp}/wrox-install-XXXXXX.log" 2>/dev/null || true)"
27
+ if [ -z "${INSTALL_LOG_FILE:-}" ]; then
28
+ INSTALL_LOG_FILE="${HOME}/wrox-install-error.log"
29
+ : > "$INSTALL_LOG_FILE"
30
+ fi
31
+
32
+ if command -v tee >/dev/null 2>&1; then
33
+ exec > >(tee -a "$INSTALL_LOG_FILE") 2>&1
34
+ fi
35
+
26
36
  # ── Utilities ──
27
37
  # shellcheck disable=SC2059
28
38
  info() { printf "${BLUE}[INFO]${NC} %s\n" "$1"; }
@@ -35,6 +45,31 @@ fail() { printf "${RED} ✗${NC} %s\n" "$1"; }
35
45
  # shellcheck disable=SC2059
36
46
  step() { printf "\n${BOLD}${CYAN}[%s]${NC} ${BOLD}%s${NC}\n" "$1" "$2"; }
37
47
 
48
+ pause_on_failure_if_interactive() {
49
+ if [ -t 1 ] && [ -r /dev/tty ]; then
50
+ printf "\nPress Enter to exit..." >/dev/tty
51
+ read -r _ </dev/tty || true
52
+ fi
53
+ }
54
+
55
+ handle_install_error() {
56
+ local exit_code=$?
57
+ local line_no="$1"
58
+ local failed_command="$2"
59
+
60
+ trap - ERR
61
+
62
+ printf "\n${RED}Installation failed.${NC}\n"
63
+ printf " Command: %s\n" "$failed_command"
64
+ printf " Line : %s\n" "$line_no"
65
+ printf " Log : %s\n" "$INSTALL_LOG_FILE"
66
+
67
+ pause_on_failure_if_interactive
68
+ exit "$exit_code"
69
+ }
70
+
71
+ trap 'handle_install_error "${LINENO}" "$BASH_COMMAND"' ERR
72
+
38
73
  # Y/n prompt (default Y)
39
74
  confirm() {
40
75
  local prompt="$1"
@@ -77,7 +112,7 @@ is_lfs_pointer() {
77
112
 
78
113
  # ── Header ──
79
114
  # shellcheck disable=SC2059
80
- printf "\n${BOLD}Weppy Roblox MCP Installer${NC}\n"
115
+ printf "\n${BOLD}WROX Installer${NC}\n"
81
116
  # shellcheck disable=SC2059
82
117
  printf "${DIM}AI-powered Roblox Studio integration${NC}\n"
83
118
  printf "%s\n" "════════════════════════════════════"
@@ -318,7 +353,7 @@ printf "${BOLD}Installation complete!${NC}\n\n"
318
353
  printf " ${BOLD}Next steps:${NC}\n"
319
354
  printf " 1. Restart Roblox Studio\n"
320
355
  # shellcheck disable=SC2059
321
- printf " 2. Look for the ${BOLD}W-MCP${NC} button in the Plugins tab\n"
356
+ printf " 2. Look for the ${BOLD}WROX${NC} button in the Plugins tab\n"
322
357
  printf " 3. Click Connect and start building with AI!\n\n"
323
358
  printf " Auto registration: Claude Code, Claude Desktop, Cursor, Codex CLI, Gemini CLI\n"
324
359
  printf " Manual setup required: Codex App, Antigravity\n\n"
package/llms-full.txt CHANGED
@@ -1,9 +1,9 @@
1
- # Weppy Roblox MCP — Full Documentation
1
+ # WROX — Full Documentation
2
2
 
3
- > Weppy Roblox MCP is an MCP server that lets AI coding agents (Claude, Codex,
3
+ > WROX is an MCP server that lets AI coding agents (Claude, Codex,
4
4
  > Cursor, Gemini) control a live Roblox Studio session — create and edit scripts,
5
5
  > instances, terrain, lighting, assets, audio, and animations via natural language.
6
- > 21 consolidated tools · 140+ actions · Bidirectional sync · Multi-place support
6
+ > Action-based MCP tools · Bidirectional sync · Multi-place support
7
7
 
8
8
  ---
9
9
 
@@ -57,12 +57,12 @@ Note: The same plugin package is used for all tiers.
57
57
  4. **Copy** the `WeppyRobloxMCP.rbxm` file into the opened Plugins folder
58
58
  5. **Restart Roblox Studio**
59
59
 
60
- After restarting, the **W-MCP** button will appear in the Plugins tab.
60
+ After restarting, the **WROX** button will appear in the Plugins tab.
61
61
 
62
62
  ### Connect to AI Agent
63
63
 
64
64
  1. Open any project in **Roblox Studio**
65
- 2. Go to **Plugins** tab -> **W-MCP**
65
+ 2. Go to **Plugins** tab -> **WROX**
66
66
  3. Click the **Connect** button in the plugin window
67
67
  4. Once **"Connected"** status is displayed, you're ready
68
68
 
@@ -201,7 +201,7 @@ In the agent pane, click ⋯ → MCP Servers → Manage MCP Servers → View raw
201
201
 
202
202
  Browse synced instance trees inside VSCode with Roblox class icons.
203
203
 
204
- Search for **Weppy Roblox Explorer** in the VSCode Extensions sidebar and click Install, or install from [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=weppy.weppy-roblox-explorer) or [Open VSX](https://open-vsx.org/extension/weppy/weppy-roblox-explorer).
204
+ Search for **WROX Explorer** in the VSCode Extensions sidebar and click Install, or install from [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=weppy.weppy-roblox-explorer) or [Open VSX](https://open-vsx.org/extension/weppy/weppy-roblox-explorer).
205
205
 
206
206
  Features:
207
207
  - Instance tree with Roblox class icons (dark/light theme)
@@ -212,7 +212,7 @@ Features:
212
212
 
213
213
  ## After Installation
214
214
 
215
- 1. Open Roblox Studio, go to Plugins tab and click W-MCP → Connect
215
+ 1. Open Roblox Studio, go to Plugins tab and click WROX → Connect
216
216
  2. Test in your AI app: "Create a blue part in Roblox Studio"
217
217
 
218
218
  ---
@@ -630,7 +630,7 @@ Claude Code, Claude Desktop, Cursor, Codex CLI, Codex Desktop, Gemini CLI, Antig
630
630
  ## Plugin not connecting
631
631
 
632
632
  1. Make sure the MCP server is running: `npx -y @weppy/roblox-mcp`
633
- 2. In Roblox Studio: Plugins tab → W-MCP → Connect
633
+ 2. In Roblox Studio: Plugins tab → WROX → Connect
634
634
  3. Confirm nothing is blocking `localhost:3002` (firewall, antivirus, VPN)
635
635
  4. Try restarting both Roblox Studio and the MCP server
636
636
 
package/llms.txt CHANGED
@@ -1,17 +1,17 @@
1
- # Weppy Roblox MCP — MCP Server for Roblox Studio
1
+ # WROX — MCP Server for Roblox Studio
2
2
 
3
- > Weppy Roblox MCP is an MCP server that lets AI coding agents (Claude, Codex,
3
+ > WROX is an MCP server that lets AI coding agents (Claude, Codex,
4
4
  > Cursor, Gemini) control a live Roblox Studio session — create and edit scripts,
5
5
  > instances, terrain, lighting, assets, audio, and animations via natural language.
6
6
 
7
7
  ## What it does
8
8
 
9
- Weppy Roblox MCP provides a real-time bridge between AI agents and the Roblox
9
+ WROX provides a real-time bridge between AI agents and the Roblox
10
10
  Studio DataModel. It exposes the full Roblox API surface as executable MCP tools,
11
11
  so AI can directly create, read, modify, and delete instances, scripts, properties,
12
12
  terrain, and more — inside a live Studio session.
13
13
 
14
- - 21 consolidated tools with 140+ actions covering the full Roblox Studio API surface
14
+ - Action-based MCP tools covering the full Roblox Studio API surface
15
15
  - Bidirectional project sync between Roblox Studio and local files (Pro)
16
16
  - Automated playtest: AI starts/stops Play/Run, injects test scripts, collects logs
17
17
  - Web dashboard: monitor AI actions, tool history, sync state, and changelog in real time at `http://localhost:3002`
@@ -46,7 +46,7 @@ Or manually:
46
46
  - Installation: https://github.com/hope1026/weppy-roblox-mcp/blob/main/docs/en/installation/README.md
47
47
  - Tools reference: https://github.com/hope1026/weppy-roblox-mcp/blob/main/docs/en/tools/overview.md
48
48
  - Sync guide: https://github.com/hope1026/weppy-roblox-mcp/blob/main/docs/en/sync/overview.md
49
- - Dashboard guide: https://github.com/hope1026/weppy-roblox-mcp/blob/main/docs/en/dashboard/overview.md
49
+ - WROX Dashboard guide: https://github.com/hope1026/weppy-roblox-mcp/blob/main/docs/en/dashboard/overview.md
50
50
  - Troubleshooting: https://github.com/hope1026/weppy-roblox-mcp/blob/main/docs/troubleshooting.md
51
51
  - Compatibility: https://github.com/hope1026/weppy-roblox-mcp/blob/main/docs/compatibility.md
52
52
  - Pro upgrade: https://github.com/hope1026/weppy-roblox-mcp/blob/main/docs/en/pro-upgrade.md
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weppy/roblox-mcp",
3
- "version": "2.0.7",
3
+ "version": "2.0.9",
4
4
  "description": "MCP (Model Context Protocol) server for Roblox Studio integration - enables AI coding agents to interact with Roblox Studio in real-time",
5
5
  "main": "plugins/weppy-roblox-mcp/dist/index.js",
6
6
  "type": "module",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "weppy-roblox-mcp",
3
3
  "description": "MCP server for Roblox Studio integration - AI-powered game development with specialized agents and skills",
4
- "version": "2.0.7",
4
+ "version": "2.0.9",
5
5
  "author": {
6
6
  "name": "hope1026"
7
7
  },
@@ -0,0 +1 @@
1
+ ._page_q2jbi_2{display:flex;flex-direction:column;gap:20px;max-width:900px}._header_q2jbi_10{display:flex;align-items:center;gap:12px}._backLink_q2jbi_16{font-family:var(--font-label);font-size:12px;color:var(--accent);cursor:pointer;text-decoration:none;transition:opacity var(--transition)}._backLink_q2jbi_16:hover{opacity:.8}._headerTitle_q2jbi_29{font-family:var(--font-label);font-size:14px;font-weight:600;color:var(--text-primary);letter-spacing:.03em}._headerTime_q2jbi_37{font-family:var(--font-code);font-size:12px;color:var(--text-secondary);margin-left:auto}._statusActive_q2jbi_44{color:var(--success);font-weight:600}._statusCompleted_q2jbi_49{color:var(--text-muted)}._section_q2jbi_54{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:16px 20px}._sectionTitle_q2jbi_61{font-family:var(--font-label);font-size:12px;font-weight:600;color:var(--text-primary);text-transform:uppercase;letter-spacing:.05em;margin-bottom:12px;padding-bottom:8px;border-bottom:1px solid var(--border)}._summaryGrid_q2jbi_74{display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:10px}._summaryCard_q2jbi_80{background:var(--bg-secondary);border:1px solid var(--border);border-radius:6px;padding:10px 12px;text-align:center;cursor:pointer;transition:border-color var(--transition)}._summaryCard_q2jbi_80:hover{border-color:var(--accent)}._summaryCardActive_q2jbi_94{border-color:var(--accent);background:var(--accent-dim)}._summaryIcon_q2jbi_99{font-size:20px;display:block;margin-bottom:4px}._summaryCount_q2jbi_105{font-family:var(--font-code);font-size:18px;font-weight:700;color:var(--text-primary)}._summaryLabel_q2jbi_112{font-family:var(--font-label);font-size:10px;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.04em;margin-top:2px}._contextGrid_q2jbi_121{display:flex;flex-direction:column;gap:10px}._contextRow_q2jbi_127{display:flex;flex-direction:column;gap:4px}._contextKey_q2jbi_133{font-family:var(--font-label);font-size:10px;color:var(--text-muted);text-transform:uppercase;letter-spacing:.05em}._contextValue_q2jbi_141{font-family:var(--font-label);font-size:13px;color:var(--text-primary);line-height:1.5}._timelineFilter_q2jbi_149{display:flex;align-items:center;gap:8px;margin-bottom:12px}._filterLabel_q2jbi_156{font-family:var(--font-label);font-size:11px;color:var(--text-secondary)}._filterSelect_q2jbi_162{font-family:var(--font-code);font-size:11px;padding:3px 8px;border:1px solid var(--border);border-radius:4px;background:var(--bg-secondary);color:var(--text-primary)}._timeline_q2jbi_149{display:flex;flex-direction:column;gap:0;position:relative;max-height:480px;overflow-y:auto}._timelineEntry_q2jbi_182{display:flex;gap:12px;padding:8px 0;border-bottom:1px solid var(--border);transition:background var(--transition);cursor:pointer}._timelineEntry_q2jbi_182:last-child{border-bottom:none}._timelineEntry_q2jbi_182:hover{background:var(--bg-secondary)}._timelineTime_q2jbi_199{font-family:var(--font-code);font-size:11px;color:var(--text-muted);min-width:50px;flex-shrink:0}._timelineIcon_q2jbi_207{font-size:14px;flex-shrink:0}._timelineBody_q2jbi_212{flex:1;min-width:0}._timelineSummary_q2jbi_217{font-family:var(--font-code);font-size:12px;color:var(--text-primary);word-break:break-all}._timelineTarget_q2jbi_224{font-family:var(--font-code);font-size:11px;color:var(--text-secondary);margin-top:2px}._timelineConfidence_q2jbi_231{font-family:var(--font-label);font-size:9px;padding:1px 5px;border-radius:3px;margin-left:8px;vertical-align:middle}._confidenceExact_q2jbi_240{background:#22c55e26;color:var(--success)}._confidencePartial_q2jbi_245{background:#f59e0b26;color:var(--warning)}._confidenceAfterOnly_q2jbi_250{background:#22c55e14;color:var(--text-secondary)}._confidenceIntentOnly_q2jbi_255{background:#ef444426;color:var(--error)}._confidenceUnknown_q2jbi_260{background:var(--bg-secondary);color:var(--text-muted)}._timelineExpanded_q2jbi_266{margin-top:8px;padding:8px;background:var(--bg-card);border:1px solid var(--border);border-radius:6px}._beforeAfterList_q2jbi_275{display:flex;flex-direction:column;gap:12px}._beforeAfterItem_q2jbi_281{background:var(--bg-secondary);border:1px solid var(--border);border-radius:6px;overflow:hidden}._beforeAfterHeader_q2jbi_288{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--bg-card);border-bottom:1px solid var(--border);cursor:pointer}._beforeAfterPath_q2jbi_298{font-family:var(--font-code);font-size:11px;color:var(--text-primary)}._beforeAfterBadge_q2jbi_304{font-family:var(--font-label);font-size:9px;padding:1px 6px;border-radius:3px;text-transform:uppercase;letter-spacing:.04em}._badgeCreate_q2jbi_313{background:#22c55e26;color:var(--success)}._badgeModify_q2jbi_318{background:#f59e0b26;color:var(--warning)}._badgeDelete_q2jbi_323{background:#ef444426;color:var(--error)}._badgeMove_q2jbi_328{background:#3b82f626;color:var(--accent)}._beforeAfterBody_q2jbi_333{padding:8px}._empty_q2jbi_338{text-align:center;padding:20px;color:var(--text-muted);font-family:var(--font-label);font-size:12px}._loading_q2jbi_347{text-align:center;padding:40px 20px;color:var(--text-secondary);font-family:var(--font-label);font-size:12px}._error_q2jbi_356{text-align:center;padding:40px 20px;color:var(--error);font-family:var(--font-label);font-size:13px}
@@ -0,0 +1 @@
1
+ import{r,a as R,u as M,b as B,c as D,j as e,T as m}from"./index-DWRH2iF4.js";import{I as V}from"./InfoLabel-DzXzzs6Q.js";import{D as F,P as G}from"./PropertyDiff-BZMdMzMr.js";function P(t){const s={scriptsModified:0,scriptsCreated:0,instancesCreated:0,instancesDeleted:0,instancesMoved:0,propertiesChanged:0,lightingChanged:!1,terrainChanged:!1,assetsInserted:0};for(const l of t)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 U(t){const[s,l]=r.useState(""),[a,d]=r.useState(""),[u,q]=r.useState(),[w,y]=r.useState("completed"),[E,I]=r.useState([]),[O,L]=r.useState([]),[f,x]=r.useState([]),[p,j]=r.useState(),[_,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(t){g(!0),h(null);try{const[c,o]=await Promise.all([R.get(`/api/dashboard/changelog/${t}`),R.get(`/api/dashboard/changelog/${t}/changes`)]);l(c.entryId),d(c.startTime),q(c.endTime),y(c.status),I(c.entries),L(c.failures),j(c.contextSummary),b(c.replayMetadata),S(c.verificationSummary),x(o.changes),N(P(o.changes))}catch(c){h(c instanceof Error?c.message:"Failed to load changelog detail")}finally{g(!1)}}},[t]);return r.useEffect(()=>{i()},[i]),{entryId:s,startTime:a,endTime:u,status:w,entries:E,failures:O,changes:f,changeSummary:C,contextSummary:p,replayMetadata:_,verificationSummary:v,loading:T,error:k,refresh:i}}const z={script:"📝",instance:"🧱",property:"🎨",lighting:"🌅",terrain:"⛰️",asset:"📦"};function H(t){return z[t]??"❓"}const J="_page_q2jbi_2",W="_header_q2jbi_10",Y="_backLink_q2jbi_16",Q="_headerTitle_q2jbi_29",X="_headerTime_q2jbi_37",Z="_statusActive_q2jbi_44",ee="_statusCompleted_q2jbi_49",te="_section_q2jbi_54",ne="_sectionTitle_q2jbi_61",ae="_summaryGrid_q2jbi_74",ie="_summaryCard_q2jbi_80",se="_summaryCardActive_q2jbi_94",ce="_summaryIcon_q2jbi_99",re="_summaryCount_q2jbi_105",oe="_summaryLabel_q2jbi_112",le="_contextGrid_q2jbi_121",de="_contextRow_q2jbi_127",me="_contextKey_q2jbi_133",ge="_contextValue_q2jbi_141",he="_timelineFilter_q2jbi_149",ue="_filterLabel_q2jbi_156",ye="_filterSelect_q2jbi_162",fe="_timeline_q2jbi_149",xe="_timelineEntry_q2jbi_182",pe="_timelineTime_q2jbi_199",je="_timelineIcon_q2jbi_207",_e="_timelineBody_q2jbi_212",be="_timelineSummary_q2jbi_217",ve="_timelineTarget_q2jbi_224",Se="_timelineConfidence_q2jbi_231",Ce="_confidenceExact_q2jbi_240",Ne="_confidencePartial_q2jbi_245",Te="_confidenceAfterOnly_q2jbi_250",ke="_confidenceIntentOnly_q2jbi_255",qe="_confidenceUnknown_q2jbi_260",we="_timelineExpanded_q2jbi_266",Ee="_empty_q2jbi_338",Ie="_loading_q2jbi_347",Oe="_error_q2jbi_356",n={page:J,header:W,backLink:Y,headerTitle:Q,headerTime:X,statusActive:Z,statusCompleted:ee,section:te,sectionTitle:ne,summaryGrid:ae,summaryCard:ie,summaryCardActive:se,summaryIcon:ce,summaryCount:re,summaryLabel:oe,contextGrid:le,contextRow:de,contextKey:me,contextValue:ge,timelineFilter:he,filterLabel:ue,filterSelect:ye,timeline:fe,timelineEntry:xe,timelineTime:pe,timelineIcon:je,timelineBody:_e,timelineSummary:be,timelineTarget:ve,timelineConfidence:Se,confidenceExact:Ce,confidencePartial:Ne,confidenceAfterOnly:Te,confidenceIntentOnly:ke,confidenceUnknown:qe,timelineExpanded:we,empty:Ee,loading:Ie,error:Oe},$=[{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(t){if(!t)return"--:--";const s=new Date(t);return`${String(s.getHours()).padStart(2,"0")}:${String(s.getMinutes()).padStart(2,"0")}`}function Le(t){if(!t)return"--:--:--";const s=new Date(t);return`${String(s.getHours()).padStart(2,"0")}:${String(s.getMinutes()).padStart(2,"0")}:${String(s.getSeconds()).padStart(2,"0")}`}function Ae(t,s){if(!t||!s)return"";const l=new Date(s).getTime()-new Date(t).getTime();return l<0?"":`${Math.round(l/6e4)}min`}function Ke(t){switch(t){case"exact":return n.confidenceExact;case"partial":return n.confidencePartial;case"after-only":return n.confidenceAfterOnly;case"intent-only":return n.confidenceIntentOnly;default:return n.confidenceUnknown}}function Re(t,s){switch(s){case"exact":return t("changelog.detail.confidence.exact","Exact");case"partial":return t("changelog.detail.confidence.partial","Partial");case"after-only":return t("changelog.detail.confidence.afterOnly","After only");case"intent-only":return t("changelog.detail.confidence.intentOnly","Intent only");default:return t("changelog.detail.confidence.unknown","Unknown")}}function $e(t,s){switch(s){case"exact":return t("changelog.detail.confidence.exact.tooltip","Both the before and after state were confirmed for this change.");case"partial":return t("changelog.detail.confidence.partial.tooltip","Only part of the before and after state could be confirmed for this change.");case"after-only":return t("changelog.detail.confidence.afterOnly.tooltip","Only the resulting state after the change could be confirmed.");case"intent-only":return t("changelog.detail.confidence.intentOnly.tooltip","Only the requested action was recorded, not the resulting state.");default:return t("changelog.detail.confidence.unknown.tooltip","This change could not be confidently classified from the available data.")}}function Fe(){var f,x,p,j,_,b,v,S,C,N,T,g,k,h;const{t}=M(),{id:s}=B(),l=D(),a=U(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:n.loading,children:t("common.loading","Loading...")});if(a.error)return e.jsxs("div",{className:n.error,children:[a.error,e.jsx("br",{}),e.jsxs("span",{className:n.backLink,onClick:()=>l("/changelog"),children:["←"," ",t("changelog.detail.backToList","Back to list")]})]});const E=Ae(a.startTime,a.endTime),I=a.endTime?`${A(a.startTime)} → ${A(a.endTime)} (${E})`:`${A(a.startTime)} → ${t("changelog.card.inProgress","in progress")}`,O=!!((f=a.contextSummary)!=null&&f.intent||(x=a.contextSummary)!=null&&x.testScenario||(p=a.contextSummary)!=null&&p.expectedBehavior||(j=a.contextSummary)!=null&&j.observedBehavior),L=!!((_=a.verificationSummary)!=null&&_.label||(b=a.verificationSummary)!=null&&b.status||(v=a.verificationSummary)!=null&&v.testTimestamp);return e.jsxs("div",{className:n.page,children:[e.jsxs("div",{className:n.header,children:[e.jsxs("span",{className:n.backLink,onClick:()=>l("/changelog"),children:["←"," ",t("sidebar.changelog","Changelog")]}),e.jsx("span",{className:n.headerTitle,children:"|"}),e.jsx("span",{className:n.headerTime,children:I}),e.jsx(m,{text:a.status==="active"?t("changelog.card.active.tooltip","This session is still receiving new game changes."):t("changelog.card.completed.tooltip","This session has ended and no more changes are expected."),children:e.jsx("span",{className:a.status==="active"?n.statusActive:n.statusCompleted,children:a.status==="active"?t("changelog.card.active","Active"):t("changelog.card.completed","Completed")})})]}),e.jsxs("div",{className:n.section,children:[e.jsx("div",{className:n.sectionTitle,children:e.jsx(m,{text:t("changelog.detail.changeSummary.tooltip","Counts of extracted game changes grouped by category for this session."),children:e.jsx("span",{children:t("changelog.detail.changeSummary","Change Summary")})})}),e.jsx("div",{className:n.summaryGrid,children:$.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:`${n.summaryCard} ${K?n.summaryCardActive:""}`,onClick:()=>u(K?"all":i.key),children:[e.jsx("span",{className:n.summaryIcon,children:i.icon}),e.jsx("div",{className:n.summaryCount,children:o}),e.jsx("div",{className:n.summaryLabel,children:t(i.labelKey,i.key)})]},i.key)})})]}),O&&e.jsxs("div",{className:n.section,children:[e.jsx("div",{className:n.sectionTitle,children:e.jsx(m,{text:t("changelog.detail.context.tooltip","Structured execution context captured for this changelog session."),children:e.jsx("span",{children:t("changelog.detail.context.title","Context Summary")})})}),e.jsxs("div",{className:n.contextGrid,children:[((S=a.contextSummary)==null?void 0:S.intent)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("changelog.card.sessionIntent","Session intent")}),e.jsx("span",{className:n.contextValue,children:a.contextSummary.intent})]}),((C=a.contextSummary)==null?void 0:C.testScenario)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("playtest.context.why","Why this test ran")}),e.jsx("span",{className:n.contextValue,children:a.contextSummary.testScenario})]}),((N=a.contextSummary)==null?void 0:N.expectedBehavior)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("playtest.context.expected","Expected")}),e.jsx("span",{className:n.contextValue,children:a.contextSummary.expectedBehavior})]}),((T=a.contextSummary)==null?void 0:T.observedBehavior)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("playtest.context.observed","Observed")}),e.jsx("span",{className:n.contextValue,children:a.contextSummary.observedBehavior})]})]})]}),L&&e.jsxs("div",{className:n.section,children:[e.jsx("div",{className:n.sectionTitle,children:e.jsx(m,{text:t("changelog.detail.verification.tooltip","Verification signals linked to this changelog session."),children:e.jsx("span",{children:t("changelog.detail.verification.title","Verification")})})}),e.jsxs("div",{className:n.contextGrid,children:[((g=a.verificationSummary)==null?void 0:g.label)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("changelog.detail.verification.label","Result")}),e.jsx("span",{className:n.contextValue,children:a.verificationSummary.label})]}),((k=a.verificationSummary)==null?void 0:k.status)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("changelog.detail.verification.status","Status")}),e.jsx("span",{className:n.contextValue,children:a.verificationSummary.status})]}),((h=a.verificationSummary)==null?void 0:h.testTimestamp)&&e.jsxs("div",{className:n.contextRow,children:[e.jsx("span",{className:n.contextKey,children:t("changelog.detail.verification.timestamp","Recorded at")}),e.jsx("span",{className:n.contextValue,children:a.verificationSummary.testTimestamp})]})]})]}),e.jsxs("div",{className:n.section,children:[e.jsx("div",{className:n.sectionTitle,children:e.jsx(m,{text:t("changelog.detail.changeTimeline.tooltip","Chronological list of extracted game changes for this session."),children:e.jsx("span",{children:t("changelog.detail.changeTimeline","Change Timeline")})})}),e.jsxs("div",{className:n.timelineFilter,children:[e.jsx("span",{className:n.filterLabel,children:e.jsx(V,{label:`${t("changelog.detail.filterCategory","Category")}:`,tooltip:t("changelog.detail.filterCategory.tooltip","Filter the timeline to a single change category.")})}),e.jsxs("select",{className:n.filterSelect,value:d,onChange:i=>u(i.target.value),children:[e.jsx("option",{value:"all",children:t("tools.filter.all","All")}),$.map(i=>e.jsxs("option",{value:i.key,children:[i.icon," ",t(i.labelKey,i.key)]},i.key))]})]}),y.length===0?e.jsx("div",{className:n.empty,children:t("changelog.detail.noChanges","No changes in this category")}):e.jsx("div",{className:n.timeline,children:y.map((i,c)=>{const o=q===c;return e.jsxs("div",{children:[e.jsxs("div",{className:n.timelineEntry,onClick:()=>w(o?null:c),children:[e.jsx("span",{className:n.timelineTime,children:Le(i.timestamp)}),e.jsx("span",{className:n.timelineIcon,children:H(i.category)}),e.jsxs("div",{className:n.timelineBody,children:[e.jsxs("div",{className:n.timelineSummary,children:[i.summary,e.jsx(m,{text:$e(t,i.confidence),children:e.jsx("span",{className:`${n.timelineConfidence} ${Ke(i.confidence)}`,children:Re(t,i.confidence)})})]}),e.jsx("div",{className:n.timelineTarget,children:i.target})]})]}),o&&e.jsx("div",{className:n.timelineExpanded,children:e.jsx(Me,{change:i})})]},c)})})]})]})}function Me({change:t}){return t.category==="script"&&(t.before||t.after)?e.jsx(F,{before:t.before,after:t.after}):t.category==="property"?e.jsx(G,{before:t.before,after:t.after}):t.details?e.jsx("pre",{style:{fontFamily:"var(--font-code)",fontSize:"11px",color:"var(--text-secondary)",margin:0,whiteSpace:"pre-wrap",wordBreak:"break-all"},children:JSON.stringify(t.details,null,2)}):e.jsx("div",{style:{fontFamily:"var(--font-code)",fontSize:"11px",color:"var(--text-muted)"},children:t.target})}export{Fe 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_1srvj_2{display:flex;flex-direction:column;gap:16px;max-width:700px}._limitNotice_1srvj_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_1srvj_18{font-family:var(--font-label);font-size:12px;color:var(--pro-text);margin-bottom:6px}._limitNoticeText_1srvj_25{font-size:12px;color:var(--text-secondary);line-height:1.5}._headerRow_1srvj_31{display:flex;align-items:center;justify-content:space-between;gap:12px}._header_1srvj_31{font-family:var(--font-label);font-size:14px;font-weight:600;color:var(--text-primary);letter-spacing:.05em;text-transform:uppercase}._clearButton_1srvj_48{border:1px solid rgba(209,84,84,.5);background:#d154541f;color:#f4c1c1;border-radius:8px;padding:6px 12px;cursor:pointer}._headerSub_1srvj_57{font-size:11px;font-weight:400;color:var(--text-muted);text-transform:none;letter-spacing:0;margin-left:8px}._filterTabs_1srvj_67{display:flex;gap:2px;border-bottom:1px solid var(--border)}._filterTab_1srvj_67{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)}._filterTab_1srvj_67:hover{color:var(--text-primary)}._filterTabActive_1srvj_90{color:var(--accent);border-bottom-color:var(--accent)}._list_1srvj_96{display:flex;flex-direction:column;gap:10px}._empty_1srvj_103{text-align:center;padding:40px 20px;color:var(--text-muted);font-family:var(--font-label);font-size:13px}._loading_1srvj_112{text-align:center;padding:40px 20px;color:var(--text-secondary);font-family:var(--font-label);font-size:12px}._pagination_1srvj_121{display:flex;align-items:center;justify-content:center;gap:12px;margin-top:4px}._pageInfo_1srvj_129{font-family:var(--font-code);font-size:12px;color:var(--text-secondary)}._btn_1srvj_135{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_1srvj_135:hover:not(:disabled){border-color:var(--accent);background:var(--accent-dim)}._btn_1srvj_135:disabled{opacity:.4;cursor:default}
@@ -0,0 +1 @@
1
+ import{r as i,a as P,D as O,u as D,j as e,T as I,c as V,i as U}from"./index-DWRH2iF4.js";import{C as G}from"./ConfirmModal-Db4rfrTo.js";import{u as H,T as Z,a as q}from"./tier-promo-config-CQFDWwo4.js";import{t as m}from"./TierPromo.module-BBX3CVXn.js";const z=10;function J(){const[t,p]=i.useState([]),[s,a]=i.useState(0),[u,f]=i.useState(!1),[r,v]=i.useState(!0),[l,C]=i.useState(0),[d,j]=i.useState("all"),b=i.useRef(null),x=i.useCallback(async(h,o)=>{v(!0);try{const S={limit:String(z),offset:String(h)};o!=="all"&&(S.status=o);const N=await P.get("/api/dashboard/changelog",S);p(N.entries),a(N.total),f(N.hasMore)}catch{p([]),a(0),f(!1)}finally{v(!1)}},[]),y=i.useCallback(()=>{x(l,d)},[x,l,d]),_=i.useCallback(async()=>{await P.post("/api/dashboard/changelog/clear"),p([]),a(0),f(!1)},[]);return i.useEffect(()=>{x(l,d)},[x,l,d]),i.useEffect(()=>{const h=new O;b.current=h,h.connect();const o=h.on("command",()=>{x(l,d)});return()=>{o(),h.disconnect(),b.current=null}},[x,l,d]),{entries:t,total:s,hasMore:u,loading:r,offset:l,statusFilter:d,setOffset:C,setStatusFilter:j,refresh:y,clear:_}}const K="_card_1n89u_2",Q="_header_1n89u_17",W="_statusBadge_1n89u_24",X="_statusDot_1n89u_35",Y="_active_1n89u_41",ee="_completed_1n89u_50",se="_timeRange_1n89u_58",te="_summaryList_1n89u_65",ae="_summaryItem_1n89u_71",ne="_summaryIcon_1n89u_80",oe="_summaryText_1n89u_86",ce="_progressBar_1n89u_91",ie="_progressFill_1n89u_99",re="_emptySummary_1n89u_112",le="_contextBlock_1n89u_120",de="_contextLabel_1n89u_129",ge="_contextValue_1n89u_137",n={card:K,header:Q,statusBadge:W,statusDot:X,active:Y,completed:ee,timeRange:se,summaryList:te,summaryItem:ae,summaryIcon:ne,summaryText:oe,progressBar:ce,progressFill:ie,emptySummary:re,contextBlock:le,contextLabel:de,contextValue:ge};function F(t){if(!t)return"--:--";const p=new Date(t);return`${String(p.getHours()).padStart(2,"0")}:${String(p.getMinutes()).padStart(2,"0")}`}function me({entry:t,onClick:p}){var S,N,k,B,L,w,A,M,R,E;const{t:s}=D(),a=t.changeSummary,u=t.status==="active",f=t.isBootstrapOnly===!0,r=[],v=a.scriptsModified+a.scriptsCreated;if(v>0){const g=[];a.scriptsModified>0&&g.push(`${a.scriptsModified} ${s("changelog.card.modified","modified")}`),a.scriptsCreated>0&&g.push(`${a.scriptsCreated} ${s("changelog.card.created","created")}`);const T=`${v} ${s("changelog.card.scripts","scripts")} ${g.join(", ")}`;r.push({icon:"📝",text:T,tooltip:s("changelog.card.scripts.tooltip","Script changes made in this session.")})}const l=a.instancesCreated+a.instancesDeleted+a.instancesMoved;if(l>0){const g=[];a.instancesCreated>0&&g.push(`${a.instancesCreated} ${s("changelog.card.created","created")}`),a.instancesDeleted>0&&g.push(`${a.instancesDeleted} ${s("changelog.card.deleted","deleted")}`),a.instancesMoved>0&&g.push(`${a.instancesMoved} ${s("changelog.card.moved","moved")}`);const T=`${l} ${s("changelog.card.instances","instances")} ${g.join(", ")}`;r.push({icon:"🧱",text:T,tooltip:s("changelog.card.instances.tooltip","Instance create, delete, move, or clone changes in this session.")})}a.propertiesChanged>0&&r.push({icon:"🎨",text:`${a.propertiesChanged} ${s("changelog.card.propertiesChanged","properties changed")}`,tooltip:s("changelog.card.propertiesChanged.tooltip","Property value changes recorded for this session.")}),a.lightingChanged&&r.push({icon:"🌅",text:s("changelog.card.lightingConfigured","Lighting configured"),tooltip:s("changelog.card.lightingConfigured.tooltip","Lighting or atmosphere settings changed in this session.")}),a.terrainChanged&&r.push({icon:"⛰️",text:s("changelog.card.terrainConfigured","Terrain configured"),tooltip:s("changelog.card.terrainConfigured.tooltip","Terrain data or terrain settings changed in this session.")}),a.assetsInserted>0&&r.push({icon:"📦",text:`${a.assetsInserted} ${s("changelog.card.assetsInserted","assets inserted")}`,tooltip:s("changelog.card.assetsInserted.tooltip","Assets inserted into the place during this session.")});const C=F(t.startTime),d=u?s("changelog.card.inProgress","in progress"):t.endTime?F(t.endTime):"--:--",j=f?s("changelog.card.bootstrapStatus","Bootstrap"):u?s("changelog.card.active","Active"):s("changelog.card.completed","Completed"),b=f?s("changelog.card.bootstrapStatus.tooltip","This session only contains the initial sync bootstrap snapshot."):u?s("changelog.card.active.tooltip","This session is still receiving new game changes."):s("changelog.card.completed.tooltip","This session has ended and no more changes are expected."),x=f?s("changelog.card.bootstrapSummary","Initial sync snapshot"):s("changelog.card.noChanges","No changes yet"),y=f?s("changelog.card.bootstrapSummary.tooltip","Initial file sync writes are collapsed into a single bootstrap snapshot row."):s("changelog.card.noChanges.tooltip","No game changes have been extracted for this session yet."),_=(N=(S=t.contextSummary)==null?void 0:S.intent)==null?void 0:N.trim(),h=((w=(L=(B=(k=t.contextSummary)==null?void 0:k.affectedAreas)==null?void 0:B[0])==null?void 0:L.label)==null?void 0:w.trim())||((M=(A=t.contextSummary)==null?void 0:A.testScenario)==null?void 0:M.trim()),o=(E=(R=t.verificationSummary)==null?void 0:R.label)==null?void 0:E.trim();return e.jsxs("div",{className:n.card,onClick:p,children:[e.jsxs("div",{className:n.header,children:[e.jsx(I,{text:b,children:e.jsxs("span",{className:`${n.statusBadge} ${u?n.active:n.completed}`,children:[e.jsx("span",{className:n.statusDot}),j]})}),e.jsxs("span",{className:n.timeRange,children:[C,"~",d]})]}),e.jsx("div",{className:n.summaryList,children:r.length>0?r.map((g,T)=>e.jsxs("div",{className:n.summaryItem,children:[e.jsx("span",{className:n.summaryIcon,children:g.icon}),e.jsx(I,{text:g.tooltip,children:e.jsx("span",{className:n.summaryText,children:g.text})})]},T)):e.jsx(I,{text:y,children:e.jsx("span",{className:n.emptySummary,style:{display:"block"},children:x})})}),_&&e.jsxs("div",{className:n.contextBlock,children:[e.jsx("span",{className:n.contextLabel,children:s("changelog.card.sessionIntent","Session intent")}),e.jsx("span",{className:n.contextValue,children:_})]}),!_&&h&&e.jsxs("div",{className:n.contextBlock,children:[e.jsx("span",{className:n.contextLabel,children:s("changelog.card.representativeArea","Representative area")}),e.jsx("span",{className:n.contextValue,children:h})]}),o&&e.jsxs("div",{className:n.contextBlock,children:[e.jsx("span",{className:n.contextLabel,children:s("changelog.card.verification","Verification")}),e.jsx("span",{className:n.contextValue,children:o})]}),u&&e.jsx("div",{className:n.progressBar,children:e.jsx("div",{className:n.progressFill})})]})}const he="_page_1srvj_2",pe="_limitNotice_1srvj_9",ue="_limitNoticeTitle_1srvj_18",fe="_limitNoticeText_1srvj_25",xe="_headerRow_1srvj_31",_e="_header_1srvj_31",ve="_clearButton_1srvj_48",je="_headerSub_1srvj_57",be="_filterTabs_1srvj_67",ye="_filterTab_1srvj_67",Ne="_filterTabActive_1srvj_90",Ce="_list_1srvj_96",Se="_empty_1srvj_103",Te="_loading_1srvj_112",$e="_pagination_1srvj_121",Ie="_pageInfo_1srvj_129",ke="_btn_1srvj_135",c={page:he,limitNotice:pe,limitNoticeTitle:ue,limitNoticeText:fe,headerRow:xe,header:_e,clearButton:ve,headerSub:je,filterTabs:be,filterTab:ye,filterTabActive:Ne,list:Ce,empty:Se,loading:Te,pagination:$e,pageInfo:Ie,btn:ke},$=10,Be=[{key:"all",label:"changelog.filter.all"},{key:"active",label:"changelog.filter.active"},{key:"completed",label:"changelog.filter.completed"}];function Re(){const{t}=D(),p=V(),s=J(),a=H(),{show:u}=U(),[f,r]=i.useState(!1),[v,l]=i.useState(!1),[C,d]=i.useState(!1),j=!a.loading&&a.tier==="basic",b=j?s.entries.slice(0,3):s.entries,x=!j&&s.total>$,y=b.length,_=s.total,h=async()=>{l(!0);try{await s.clear(),u(t("toast.clearSuccess","Cleared successfully"),"success"),r(!1)}catch{u(t("toast.clearFailed","Failed to clear data"),"error")}finally{l(!1)}};return e.jsxs("div",{className:c.page,children:[e.jsxs("div",{className:c.headerRow,children:[e.jsxs("h2",{className:c.header,children:[t("sidebar.changelog","Changelog"),e.jsx("span",{className:c.headerSub,children:t("changelog.subtitle","Game Change History")})]}),e.jsx("button",{className:c.clearButton,onClick:()=>r(!0),children:t("common.clear","Clear")})]}),e.jsx("div",{className:c.filterTabs,children:Be.map(o=>e.jsx("button",{className:`${c.filterTab} ${s.statusFilter===o.key?c.filterTabActive:""}`,onClick:()=>{s.setStatusFilter(o.key),s.setOffset(0)},children:t(o.label,o.key.charAt(0).toUpperCase()+o.key.slice(1))},o.key))}),s.loading&&s.entries.length===0&&e.jsx("div",{className:c.loading,children:t("common.loading","Loading...")}),!s.loading&&s.entries.length===0?e.jsx("div",{className:c.empty,children:t("changelog.empty","No changelog entries yet")}):e.jsx("div",{className:c.list,children:b.map(o=>e.jsx(me,{entry:o,onClick:()=>p(`/changelog/${o.entryId}`)},o.entryId))}),x&&e.jsxs("div",{className:c.pagination,children:[e.jsx("button",{className:c.btn,disabled:s.offset===0,onClick:()=>s.setOffset(Math.max(0,s.offset-$)),children:t("tools.page.prev","Prev")}),e.jsxs("span",{className:c.pageInfo,children:[s.offset+1,"–",Math.min(s.offset+$,s.total)," / ",s.total]}),e.jsx("button",{className:c.btn,disabled:!s.hasMore,onClick:()=>s.setOffset(s.offset+$),children:t("tools.page.next","Next")})]}),j&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:c.limitNotice,children:[e.jsx("div",{className:c.limitNoticeTitle,children:t("changelog.basic.limit.title","Basic preview shows the latest 3 sessions")}),e.jsx("div",{className:c.limitNoticeText,children:t("changelog.basic.limit.body","Upgrade to Pro to browse the full changelog timeline for this place.")})]}),e.jsxs("div",{className:m.progressPromo,children:[e.jsxs("div",{className:m.progressMain,children:[e.jsxs("div",{className:m.progressLabel,children:[e.jsx("span",{children:t("changelog.basic.metricLabel","Visible Changelog / Total")}),e.jsxs("span",{children:[y," / ",_]})]}),e.jsx("div",{className:m.progressBar,children:e.jsx("div",{className:m.progressFill,style:{width:`${_>0?Math.min(y/_*100,100):0}%`}})}),e.jsxs("div",{className:m.progressLabel,children:[e.jsxs("span",{children:[y," ",t("changelog.basic.visible","visible")]}),e.jsxs("span",{children:[_," ",t("changelog.basic.total","total")]})]})]}),e.jsx("span",{className:m.progressText,children:t("tier.banner.save","Save AI tokens with Pro!")}),e.jsxs("div",{className:m.actions,children:[e.jsx("button",{className:`${m.btn} ${m.btnOutline}`,onClick:()=>d(!0),children:t("tier.compare","Basic vs Pro")}),e.jsx("a",{className:`${m.btn} ${m.btnPrimary}`,href:Z.changelog,target:"_blank",rel:"noreferrer",children:t("tier.upgrade","Upgrade to Pro")})]})]})]}),e.jsx(G,{open:f,title:t("changelog.clear.title","Clear changelog?"),message:t("changelog.clear.message","This permanently removes the stored changelog for the current place."),cancelLabel:t("common.cancel","Cancel"),confirmLabel:t("common.clear","Clear"),loading:v,onCancel:()=>!v&&r(!1),onConfirm:h}),C&&e.jsx(q,{onClose:()=>d(!1)})]})}export{Re as Component};
@@ -1 +1 @@
1
- import{j as t}from"./index-CkXvRg-O.js";const d="_backdrop_1ct9h_1",_="_modal_1ct9h_11",h="_title_1ct9h_20",u="_message_1ct9h_26",p="_actions_1ct9h_32",x="_cancelButton_1ct9h_39",f="_confirmButton_1ct9h_40",c={backdrop:d,modal:_,title:h,message:u,actions:p,cancelButton:x,confirmButton:f};function b({open:n,title:a,message:e,cancelLabel:l,confirmLabel:i,loading:s=!1,onCancel:o,onConfirm:r}){return n?t.jsx("div",{className:c.backdrop,onClick:s?void 0:o,children:t.jsxs("div",{className:c.modal,onClick:m=>m.stopPropagation(),children:[t.jsx("h2",{className:c.title,children:a}),t.jsx("p",{className:c.message,children:e}),t.jsxs("div",{className:c.actions,children:[t.jsx("button",{className:c.cancelButton,onClick:o,disabled:s,children:l}),t.jsx("button",{className:c.confirmButton,onClick:r,disabled:s,children:s?"...":i})]})]})}):null}export{b as C};
1
+ import{j as t}from"./index-DWRH2iF4.js";const d="_backdrop_1ct9h_1",_="_modal_1ct9h_11",h="_title_1ct9h_20",u="_message_1ct9h_26",p="_actions_1ct9h_32",x="_cancelButton_1ct9h_39",f="_confirmButton_1ct9h_40",c={backdrop:d,modal:_,title:h,message:u,actions:p,cancelButton:x,confirmButton:f};function b({open:n,title:a,message:e,cancelLabel:l,confirmLabel:i,loading:s=!1,onCancel:o,onConfirm:r}){return n?t.jsx("div",{className:c.backdrop,onClick:s?void 0:o,children:t.jsxs("div",{className:c.modal,onClick:m=>m.stopPropagation(),children:[t.jsx("h2",{className:c.title,children:a}),t.jsx("p",{className:c.message,children:e}),t.jsxs("div",{className:c.actions,children:[t.jsx("button",{className:c.cancelButton,onClick:o,disabled:s,children:l}),t.jsx("button",{className:c.confirmButton,onClick:r,disabled:s,children:s?"...":i})]})]})}):null}export{b as C};
@@ -0,0 +1 @@
1
+ import{u as $,r,j as e,d as R,a as N,D as I,i as L,T as M}from"./index-DWRH2iF4.js";import{I as a}from"./InfoLabel-DzXzzs6Q.js";import{S as A}from"./StatusBadge-DtcYlxe-.js";import{C as E}from"./ConfirmModal-Db4rfrTo.js";import{u as P,f as k}from"./useLiveUptime-5lD1XKnw.js";const T="_container_1h084_2",H="_entry_1h084_14",B="_timestamp_1h084_21",D="_message_1h084_27",F="_warn_1h084_34",U="_error_1h084_39",G="_empty_1h084_44",v={container:T,entry:H,timestamp:B,message:D,warn:F,error:U,empty:G};function O(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 V({entries:n}){const{t}=$(),o=r.useRef(null);return r.useEffect(()=>{const l=o.current;l&&(l.scrollTop=l.scrollHeight)},[n.length]),e.jsx("div",{ref:o,className:v.container,children:n.length===0?e.jsx("div",{className:v.empty,children:t("connection.log.empty","No events yet")}):n.map((l,u)=>e.jsxs("div",{className:`${v.entry} ${l.type?v[l.type]:""}`,children:[e.jsx("span",{className:v.timestamp,children:O(l.timestamp)}),e.jsx("span",{className:v.message,children:l.message})]},u))})}const S=50;function q(){const n=new Date;return`${String(n.getHours()).padStart(2,"0")}:${String(n.getMinutes()).padStart(2,"0")}`}function X(){const{level:n,status:t,error:o}=R(),[l,u]=r.useState(null),[y,h]=r.useState([]),g=r.useRef(null),_=r.useCallback((i,f)=>{h(d=>{const p=[...d,{timestamp:q(),message:i,type:f}];return p.length>S?p.slice(-S):p})},[]),x=r.useCallback(async()=>{try{const i=await N.get("/connection-info");u(i)}catch{u(null)}},[]),j=r.useCallback(async()=>{try{const i=await N.get("/api/dashboard/connection-log");h(i.entries??[])}catch{h([])}},[]),C=r.useCallback(async()=>{await N.post("/api/dashboard/connection-log/clear"),h([])},[]);return r.useEffect(()=>{n!=="L0"&&t&&x(),j()},[n,t,x,j]),r.useEffect(()=>{const i=new I;g.current=i,i.connect();const f=i.on("connection",p=>{const m=p,b=m.status==="connected"?"connected":"disconnected";_(`Plugin ${b} — ${m.clientId}`,m.status==="connected"?"info":"warn")}),d=i.on("mcp_status",p=>{const m=p,b=m.status==="registered"?"registered":"unregistered";_(`MCP ${b} — ${m.aiClientName}`,m.status==="registered"?"info":"warn"),x()});return()=>{f(),d(),i.disconnect(),g.current=null}},[_,x]),{status:t,connectionInfo:l,connectionLog:y,level:n,error:o,clearConnectionLog:C}}const z="_page_12byi_2",J="_card_12byi_10",K="_disabled_12byi_18",Q="_cardHeader_12byi_24",W="_clearButton_12byi_37",Y="_serverGrid_12byi_47",Z="_statusRow_12byi_65",ee="_table_12byi_79",ne="_toggleBtn_12byi_104",te="_disconnected_12byi_119",se="_disconnectedActions_12byi_136",oe="_btn_12byi_143",ce="_emptyRow_12byi_161",s={page:z,card:J,disabled:K,cardHeader:Q,clearButton:W,serverGrid:Y,statusRow:Z,table:ee,toggleBtn:ne,disconnected:te,disconnectedActions:se,btn:oe,emptyRow:ce};function w(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 pe(){var b;const{t:n}=$(),{status:t,connectionInfo:o,connectionLog:l,level:u,clearConnectionLog:y}=X(),{show:h}=L(),[g,_]=r.useState(!0),[x,j]=r.useState(!1),[C,i]=r.useState(!1),f=P(t==null?void 0:t.uptime),d=u==="L0",p=d?"offline":"online",m=async()=>{i(!0);try{await y(),h(n("toast.clearSuccess","Cleared successfully"),"success"),j(!1)}catch{h(n("toast.clearFailed","Failed to clear data"),"error")}finally{i(!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")}),d?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(A,{status:p})}),e.jsxs("dl",{className:s.serverGrid,children:[(t==null?void 0:t.version)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(a,{label:n("connection.server.version","Version"),tooltip:n("connection.server.version.tooltip","Installed MCP server version")})}),e.jsx("dd",{children:e.jsx(M,{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(a,{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(a,{label:n("connection.server.uptime","Uptime"),tooltip:n("connection.server.uptime.tooltip","Time elapsed since the MCP server started")})}),e.jsx("dd",{children:k(f??t.uptime)})]}),(t==null?void 0:t.sessionId)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(a,{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(a,{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} ${d?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:()=>_(c=>!c),"aria-label":g?n("common.collapse","Collapse"):n("common.expand","Expand"),children:g?"▾":"▸"})]}),g&&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(a,{label:n("connection.server.pid","PID"),tooltip:n("connection.server.pid.tooltip","Operating system process identifier")})}),e.jsx("th",{children:e.jsx(a,{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("tbody",{children:o!=null&&o.mcpInstances&&o.mcpInstances.length>0?o.mcpInstances.map(c=>e.jsxs("tr",{children:[e.jsx("td",{children:c.aiClientName??n("connection.agents.unknown","Unknown")}),e.jsx("td",{children:c.pid}),e.jsx("td",{children:c.projectRoot??c.cwd??n("connection.agents.projectRoot.unresolved","Unresolved")}),e.jsx("td",{children:w(c.connectedAt,n)})]},c.instanceId)):e.jsx("tr",{children:e.jsx("td",{colSpan:4,className:s.emptyRow,children:n("connection.agents.none","No agents connected")})})})]})]}),e.jsxs("div",{className:`${s.card} ${d?s.disabled:""}`,children:[e.jsxs("div",{className:s.cardHeader,children:[n("connection.plugins.title","Plugins")," ","(",((b=t==null?void 0:t.pluginClients)==null?void 0:b.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(a,{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(a,{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(a,{label:n("connection.plugins.version","Ver"),tooltip:n("connection.plugins.version.tooltip","Installed plugin version reported by Studio")})})]})}),e.jsx("tbody",{children:t!=null&&t.pluginClients&&t.pluginClients.length>0?t.pluginClients.map(c=>e.jsxs("tr",{children:[e.jsx("td",{children:c.placeName??c.projectName??"-"}),e.jsx("td",{children:c.clientId.slice(0,10)}),e.jsx("td",{children:w(c.lastSeen,n)}),e.jsx("td",{children:c.pluginVersion??"-"})]},c.clientId)):e.jsx("tr",{children:e.jsx("td",{colSpan:4,className:s.emptyRow,children:n("connection.plugins.none","No plugins connected")})})})]})]}),e.jsxs("div",{className:`${s.card} ${d?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:()=>j(!0),children:n("common.clear","Clear")})]}),e.jsx(V,{entries:l})]}),e.jsx(E,{open:x,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:C,onCancel:()=>!C&&j(!1),onConfirm:m})]})}export{pe as Component};
@@ -1 +1 @@
1
- import{j as r,f as e}from"./index-CkXvRg-O.js";function s({label:t,tooltip:o}){return r.jsx(e,{text:o,children:t})}export{s as I};
1
+ import{j as r,m as e}from"./index-DWRH2iF4.js";function s({label:t,tooltip:o}){return r.jsx(e,{text:o,children:t})}export{s as I};
@@ -0,0 +1 @@
1
+ ._page_1xgxh_2{display:flex;flex-direction:column;gap:16px;max-width:820px}._card_1xgxh_10{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:16px 20px}._cardHeader_1xgxh_17{font-family:var(--font-label);font-weight:500;font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-secondary);margin-bottom:12px}._disconnectCard_1xgxh_28{background:var(--bg-card);border:1px solid var(--error);border-radius:var(--radius);padding:40px 32px;text-align:center}._disconnectIcon_1xgxh_36{font-size:48px;margin-bottom:16px}._disconnectTitle_1xgxh_41{color:var(--error);font-size:18px;font-weight:600;margin:0 0 8px}._disconnectMessage_1xgxh_48{color:var(--text-secondary);font-size:14px;margin:0 0 24px}._reconnectGuide_1xgxh_55{display:flex;flex-direction:column;gap:8px;max-width:360px;margin:0 auto 20px;text-align:left}._guideStep_1xgxh_64{display:flex;align-items:center;gap:12px;font-size:13px;color:var(--text-primary)}._stepNumber_1xgxh_72{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:50%;background:var(--accent-dim);color:var(--accent);font-family:var(--font-code);font-size:12px;font-weight:600;flex-shrink:0}._reconnectIndicator_1xgxh_88{display:flex;align-items:center;justify-content:center;gap:8px;font-size:12px;color:var(--text-muted);margin-bottom:20px}._reconnectDot_1xgxh_98{width:8px;height:8px;border-radius:50%;background:var(--warning);animation:_pulse_1xgxh_1 1.5s ease-in-out infinite}@keyframes _pulse_1xgxh_1{0%,to{opacity:.4}50%{opacity:1}}._disconnectActions_1xgxh_112{display:flex;gap:8px;justify-content:center}._btn_1xgxh_118{font-family:var(--font-label);font-size:12px;padding:8px 16px;border-radius:4px;border:1px solid var(--accent);background:var(--accent);color:var(--bg-primary);cursor:pointer;transition:opacity var(--transition)}._btn_1xgxh_118:hover{opacity:.85}._btnSecondary_1xgxh_134{font-family:var(--font-label);font-size:12px;padding:8px 16px;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)}._btnSecondary_1xgxh_134:hover{border-color:var(--accent);background:var(--accent-dim)}._metricRow_1xgxh_152,._metricGrid_1xgxh_158{display:grid;grid-template-columns:1fr 1fr;gap:16px}._metricCard_1xgxh_164{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:16px 20px;display:flex;flex-direction:column;gap:6px}._metric_ok_1xgxh_174{border-color:var(--success);box-shadow:0 0 0 1px #22c55e14}._metric_warn_1xgxh_179{border-color:var(--warning);box-shadow:0 0 0 1px #f59e0b14}._metric_error_1xgxh_184{border-color:var(--error);box-shadow:0 0 0 1px #ef444414}._metricHeader_1xgxh_189{display:flex;align-items:center;gap:6px;font-family:var(--font-label);font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-secondary)}._metricIcon_1xgxh_200{font-size:14px}._metricTitle_1xgxh_204{flex:1}._metricValue_1xgxh_208{font-family:var(--font-code);font-size:18px;font-weight:600;color:var(--text-primary)}._metricSubtitle_1xgxh_215{font-family:var(--font-code);font-size:11px;color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._guideCard_1xgxh_225{background:var(--bg-card);border:1px solid var(--warning);border-radius:var(--radius);padding:16px 20px}._guideTitle_1xgxh_232{font-size:14px;font-weight:500;color:var(--text-primary);margin:0 0 12px}._checklist_1xgxh_239{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:8px}._checklist_1xgxh_239 li{font-size:13px;color:var(--text-secondary);padding-left:24px;position:relative}._checklist_1xgxh_239 li:before{content:"○";position:absolute;left:4px;color:var(--text-muted)}._feedEmpty_1xgxh_263{color:var(--text-muted);font-style:italic;font-size:13px;padding:12px 0}._feedList_1xgxh_270{display:flex;flex-direction:column;gap:4px;max-height:320px;overflow-y:auto}._feedItem_1xgxh_278{display:flex;align-items:baseline;gap:8px;font-size:12px;padding:4px 0;border-bottom:1px solid var(--border)}._feedItem_1xgxh_278:last-child{border-bottom:none}._feedTime_1xgxh_291{font-family:var(--font-code);color:var(--text-muted);flex-shrink:0;width:40px}._feedIcon_1xgxh_298{flex-shrink:0;width:18px;text-align:center}._feedSummary_1xgxh_304{color:var(--text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}._feedText_1xgxh_313{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}._feedContext_1xgxh_321{font-size:11px;color:var(--text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._feedItemClickable_1xgxh_330{cursor:pointer}._feedItemClickable_1xgxh_330:hover{background:var(--bg-secondary)}._feedChevron_1xgxh_338{flex-shrink:0;font-size:10px;color:var(--text-muted);width:14px;text-align:center}._feedDetail_1xgxh_347{padding:8px 12px;margin:2px 0 6px;background:var(--bg-secondary);border:1px solid var(--border);border-radius:6px;overflow-x:auto}._feedDetailPre_1xgxh_356{font-family:var(--font-code);font-size:11px;color:var(--text-secondary);margin:0;white-space:pre-wrap;word-break:break-all}._feedDetailText_1xgxh_365{font-family:var(--font-code);font-size:11px;color:var(--text-muted)}._changelogSummary_1xgxh_372{display:flex;flex-wrap:wrap;gap:8px;font-family:var(--font-code);font-size:12px;color:var(--text-secondary)}._changeTag_1xgxh_381{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:3px;background:var(--bg-secondary);border:1px solid var(--border);white-space:nowrap}._tierBar_1xgxh_393{display:flex;flex-direction:column;gap:6px}._tierBarTrack_1xgxh_399{display:flex;height:8px;border-radius:4px;overflow:hidden;background:var(--bg-secondary)}._tierBarFillBasic_1xgxh_407{background:var(--text-muted);transition:width .3s ease}._tierBarFillPro_1xgxh_412{background:var(--accent);transition:width .3s ease}._tierLabels_1xgxh_417{display:flex;justify-content:space-between;font-family:var(--font-code);font-size:11px;color:var(--text-muted)}
@@ -0,0 +1 @@
1
+ import{j as t,u as L,r as u,d as G,a as D,D as F,T as U}from"./index-DWRH2iF4.js";import{I as V}from"./InfoLabel-DzXzzs6Q.js";import{S as A}from"./StatusBadge-DtcYlxe-.js";import{D as z,P as O}from"./PropertyDiff-BZMdMzMr.js";import{u as J,T as X}from"./tier-promo-config-CQFDWwo4.js";import{u as q,f as K}from"./useLiveUptime-5lD1XKnw.js";import{T as Q}from"./TierPromoProgress-r5fgmYI5.js";import"./TierPromo.module-BBX3CVXn.js";const W="_page_1xgxh_2",Y="_card_1xgxh_10",Z="_cardHeader_1xgxh_17",ee="_disconnectCard_1xgxh_28",te="_disconnectIcon_1xgxh_36",se="_disconnectTitle_1xgxh_41",ne="_disconnectMessage_1xgxh_48",ie="_reconnectGuide_1xgxh_55",re="_guideStep_1xgxh_64",ce="_stepNumber_1xgxh_72",ae="_reconnectIndicator_1xgxh_88",oe="_reconnectDot_1xgxh_98",le="_pulse_1xgxh_1",de="_disconnectActions_1xgxh_112",me="_btn_1xgxh_118",xe="_btnSecondary_1xgxh_134",ge="_metricRow_1xgxh_152",he="_metricGrid_1xgxh_158",ue="_metricCard_1xgxh_164",ve="_metric_ok_1xgxh_174",_e="_metric_warn_1xgxh_179",pe="_metric_error_1xgxh_184",fe="_metricHeader_1xgxh_189",je="_metricIcon_1xgxh_200",Ce="_metricTitle_1xgxh_204",we="_metricValue_1xgxh_208",Ne="_metricSubtitle_1xgxh_215",ye="_guideCard_1xgxh_225",Te="_guideTitle_1xgxh_232",Se="_checklist_1xgxh_239",be="_feedEmpty_1xgxh_263",Ie="_feedList_1xgxh_270",ke="_feedItem_1xgxh_278",De="_feedTime_1xgxh_291",Me="_feedIcon_1xgxh_298",Pe="_feedSummary_1xgxh_304",Ee="_feedText_1xgxh_313",Be="_feedContext_1xgxh_321",He="_feedItemClickable_1xgxh_330",Re="_feedChevron_1xgxh_338",Le="_feedDetail_1xgxh_347",$e="_feedDetailPre_1xgxh_356",Ge="_feedDetailText_1xgxh_365",Fe="_changelogSummary_1xgxh_372",Ue="_changeTag_1xgxh_381",Ve="_tierBar_1xgxh_393",Ae="_tierBarTrack_1xgxh_399",ze="_tierBarFillBasic_1xgxh_407",Oe="_tierBarFillPro_1xgxh_412",Je="_tierLabels_1xgxh_417",s={page:W,card:Y,cardHeader:Z,disconnectCard:ee,disconnectIcon:te,disconnectTitle:se,disconnectMessage:ne,reconnectGuide:ie,guideStep:re,stepNumber:ce,reconnectIndicator:ae,reconnectDot:oe,pulse:le,disconnectActions:de,btn:me,btnSecondary:xe,metricRow:ge,metricGrid:he,metricCard:ue,metric_ok:ve,metric_warn:_e,metric_error:pe,metricHeader:fe,metricIcon:je,metricTitle:Ce,metricValue:we,metricSubtitle:Ne,guideCard:ye,guideTitle:Te,checklist:Se,feedEmpty:be,feedList:Ie,feedItem:ke,feedTime:De,feedIcon:Me,feedSummary:Pe,feedText:Ee,feedContext:Be,feedItemClickable:He,feedChevron:Re,feedDetail:Le,feedDetailPre:$e,feedDetailText:Ge,changelogSummary:Fe,changeTag:Ue,tierBar:Ve,tierBarTrack:Ae,tierBarFillBasic:ze,tierBarFillPro:Oe,tierLabels:Je};function N({title:e,value:i,icon:r,subtitle:c,status:a,children:n}){const d=a?s[`metric_${a}`]:"";return t.jsxs("div",{className:`${s.metricCard} ${d}`,children:[t.jsxs("div",{className:s.metricHeader,children:[r&&t.jsx("span",{className:s.metricIcon,children:r}),t.jsx("span",{className:s.metricTitle,children:e})]}),t.jsx("div",{className:s.metricValue,children:i}),c&&t.jsx("div",{className:s.metricSubtitle,children:c}),n]})}function Xe(e){var r,c;const i=e==null?void 0:e.contextSummary;return(i==null?void 0:i.intent)??((c=(r=i==null?void 0:i.affectedAreas)==null?void 0:r[0])==null?void 0:c.label)??(i==null?void 0:i.testScenario)??null}function E({changes:e}){const{t:i}=L(),[r,c]=u.useState(null);return e.length===0?t.jsx("div",{className:s.feedEmpty,children:i("overview.feed.empty")}):t.jsx("div",{className:s.feedList,children:e.map((a,n)=>{const d=r===n,o=a.raw,v=o&&(o.before!=null||o.after!=null||o.details!=null),_=Xe(o);return t.jsxs("div",{children:[t.jsxs("div",{className:`${s.feedItem} ${v?s.feedItemClickable:""}`,onClick:()=>v&&c(d?null:n),children:[t.jsx("span",{className:s.feedTime,children:a.timestamp}),t.jsx("span",{className:s.feedIcon,children:a.icon}),t.jsxs("span",{className:s.feedText,children:[t.jsx("span",{className:s.feedSummary,children:a.summary}),_&&t.jsx("span",{className:s.feedContext,children:_})]}),v&&t.jsx("span",{className:s.feedChevron,children:d?"▴":"▾"})]}),d&&o&&t.jsx("div",{className:s.feedDetail,children:t.jsx(qe,{change:o})})]},n)})})}function qe({change:e}){return e.category==="script"&&(e.before||e.after)?t.jsx(z,{before:e.before,after:e.after}):e.category==="property"?t.jsx(O,{before:e.before,after:e.after}):e.details?t.jsx("pre",{className:s.feedDetailPre,children:JSON.stringify(e.details,null,2)}):t.jsx("div",{className:s.feedDetailText,children:e.target})}const B=20;function $(e){return`${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`}function H(){return $(new Date)}function R(e){switch(e){case"script":return"📝";case"instance":return"🧱";case"property":return"🎨";case"lighting":return"💡";case"terrain":return"⛰️";case"asset":return"📦";default:return"🔧"}}function Ke(){const{level:e,status:i}=G(),r=J(),[c,a]=u.useState(null),[n,d]=u.useState(null),[o,v]=u.useState(null),[_,g]=u.useState([]),y=u.useRef(null),T=u.useCallback(async()=>{try{const l=await D.get("/connection-info");a(l)}catch{a(null)}},[]),S=u.useCallback(async()=>{try{const l=await D.get("/api/dashboard/changelog/active");if(v(l),l.recentChanges&&l.recentChanges.length>0){const p=l.recentChanges.map(h=>({timestamp:h.timestamp?$(new Date(h.timestamp)):H(),icon:R(h.category),summary:h.summary,category:h.category,raw:h}));g(p)}}catch{v(null)}},[]),f=u.useCallback(async()=>{try{const l=await D.get("/sync/status");d(l)}catch{d(null)}},[]);return u.useEffect(()=>{e!=="L0"?(T(),S(),f()):(a(null),d(null),v(null));const l=new F;y.current=l,l.connect();const p=l.on("game_change",j=>{const m=j,C={timestamp:H(),icon:R(m.category),summary:m.summary,category:m.category};g(k=>{const w=[C,...k];return w.length>B?w.slice(0,B):w}),S()}),h=l.on("sync",j=>{const m=j;d(C=>({...C,state:m.status,...m.placeId?{placeId:m.placeId}:{}}))});return()=>{p(),h(),l.disconnect(),y.current=null}},[e,T,S,f]),{level:e,status:i,connectionInfo:c,syncStatus:n,changeSummary:o,recentChanges:_,tier:r}}function M(e){return e.scriptsModified+e.scriptsCreated+e.instancesCreated+e.instancesDeleted+e.instancesMoved+e.propertiesChanged+e.assetsInserted+(e.lightingChanged?1:0)+(e.terrainChanged?1:0)}function Qe(e,i){switch(e){case"syncing":return i("status.syncing","Syncing");case"initializing":return i("status.initializing","Initializing");case"error":return i("status.error","Error");default:return i("status.idle","Idle")}}function We(e){switch(e){case"syncing":return"ok";case"initializing":return"warn";case"error":return"error";default:return"ok"}}function I(e,i,r,c){return t.jsxs("div",{className:e.metricSubtitle,children:[t.jsx(V,{label:i,tooltip:r}),": ",c]},i)}function x(e,i){return t.jsx(U,{text:i,children:e})}function ct(){var w,P;const{t:e}=L(),{level:i,status:r,connectionInfo:c,syncStatus:a,changeSummary:n,recentChanges:d,tier:o}=Ke(),v=q(r==null?void 0:r.uptime);if(i==="L0")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 _=(c==null?void 0:c.mcpInstanceCount)??0,g=((w=c==null?void 0:c.mcpInstances)==null?void 0:w.find(b=>!b.isServer&&b.aiClientName))??((P=c==null?void 0:c.mcpInstances)==null?void 0:P.find(b=>!!b.aiClientName))??null,y=(r==null?void 0:r.pluginClients)??[],T=y.length>0,S=(r==null?void 0:r.sessionId)??(c==null?void 0:c.sessionId)??"-",f=e("overview.metric.server.tooltip","MCP server runtime and process status"),l=e("overview.metric.plugin.tooltip","Roblox Studio plugin connection and version status"),p=e("overview.metric.agent.tooltip","Connected AI coding agents and their runtime state"),h=e("overview.metric.sync.tooltip","Current Studio to local sync activity"),j=r?[I(s,e("overview.meta.version","Version"),e("overview.meta.version.tooltip","Installed MCP server version"),`v${r.version}`),I(s,e("overview.meta.session","Session"),e("overview.meta.session.tooltip","Current MCP session identifier"),S),I(s,e("overview.meta.pid","PID"),e("overview.meta.pid.tooltip","Operating system process identifier"),String(r.pid??"-")),I(s,e("overview.meta.uptime","Uptime"),e("overview.meta.uptime.tooltip","Time elapsed since the MCP server started"),K(v??r.uptime))]:[];if(i==="L1")return t.jsxs("div",{className:s.page,children:[t.jsxs("div",{className:s.metricRow,children:[t.jsx(N,{title:x(e("overview.metric.server"),f),value:x(e("status.online"),f),icon:"🖥️",status:"ok",children:t.jsxs(t.Fragment,{children:[j,t.jsx(A,{status:"online"})]})}),t.jsx(N,{title:x(e("overview.metric.agent"),p),value:x((g==null?void 0:g.aiClientName)??e("overview.metric.noAgent"),p),icon:"🤖",subtitle:_>1?`${_} ${e("overview.metric.agent.instancesUnit","instances")}`:void 0,status:g?"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.jsx("li",{children:e("overview.l1.check3")})]})]}),t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.feed.title")}),d.length>0?t.jsx(E,{changes:d}):t.jsx("div",{className:s.feedEmpty,children:e("overview.l1.feedHint")})]}),n&&M(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"),": ",M(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 m=y[0],C=n?M(n):0,k=!!n&&C>0;return t.jsxs("div",{className:s.page,children:[t.jsxs("div",{className:s.metricGrid,children:[t.jsx(N,{title:x(e("overview.metric.server"),f),value:x(e("status.online"),f),icon:"🖥️",status:"ok",children:t.jsx(t.Fragment,{children:j})}),t.jsx(N,{title:x(e("overview.metric.plugin"),l),value:x(e(T?"status.online":"status.offline"),l),icon:"🔌",subtitle:m?`${m.placeName??m.projectName??"-"} / v${m.pluginVersion??"-"}`:void 0,status:T?"ok":"error"}),t.jsx(N,{title:x(e("overview.metric.agent"),p),value:x((g==null?void 0:g.aiClientName)??e("overview.metric.noAgent"),p),icon:"🤖",subtitle:_>1?`${_} ${e("overview.metric.agent.instancesUnit","instances")}`:void 0,status:g?"ok":"warn"}),t.jsx(N,{title:x(e("overview.metric.sync"),h),value:x(Qe(a==null?void 0:a.state,e),h),icon:"🔄",status:We(a==null?void 0:a.state)})]}),t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.feed.title")}),t.jsx(E,{changes:d})]}),k&&t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.changelog.title")}),t.jsxs("div",{className:s.changelogSummary,children:[t.jsxs("span",{children:[e("overview.changelog.entries","Entries"),": ",C]}),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")]})]})]}),!o.loading&&o.tier==="basic"&&o.totalCalls>0&&t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.tier.title")}),t.jsx(Q,{basicCalls:o.basicCalls,proCalls:o.proCalls,totalCalls:o.totalCalls,proUsagePercent:o.proUsagePercent,upgradeHref:X.overview})]})]})}export{ct as Component};
@@ -0,0 +1,11 @@
1
+ import{r as n,a as f,u as j,j as e,T as _,i as A}from"./index-DWRH2iF4.js";import{u as H,T as D,a as E}from"./tier-promo-config-CQFDWwo4.js";import{I as P}from"./InfoLabel-DzXzzs6Q.js";import{C as U}from"./ConfirmModal-Db4rfrTo.js";const $=5e3;function O(t){const o=(t==null?void 0:t.enabled)??!0,[d,r]=n.useState([]),[a,i]=n.useState(null),[p,l]=n.useState(o),c=n.useRef(null),m=n.useCallback(async()=>{try{const y=await f.get("/api/dashboard/playtest/history");r(y.entries??[])}catch{r([])}},[]),u=n.useCallback(async()=>{if(!o){l(!1);return}await m(),l(!1)},[o,m]),x=n.useCallback(async()=>{o&&(await f.post("/api/dashboard/playtest/history/clear"),r([]),i(null))},[o]),v=n.useCallback(async y=>{if(o)try{const S=await f.get(`/api/dashboard/playtest/report/${y}`);i(S)}catch{i(null)}},[o]);return n.useEffect(()=>{if(!o){l(!1);return}return u(),c.current=setInterval(u,$),()=>{c.current&&clearInterval(c.current)}},[o,u]),{history:d,selectedReport:a,loading:p,loadReport:v,clearHistory:x}}function F(t){const o="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:o,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 W="_page_1ge4x_2",V="_sampleBanner_1ge4x_9",z="_sampleBannerMain_1ge4x_22",G="_sampleBadge_1ge4x_29",X="_sampleTitle_1ge4x_44",Y="_sampleMessage_1ge4x_51",Z="_sampleActions_1ge4x_58",q="_primaryAction_1ge4x_66",J="_secondaryAction_1ge4x_67",K="_card_1ge4x_103",Q="_cardHeader_1ge4x_110",ee="_clearButton_1ge4x_122",te="_statusRow_1ge4x_137",se="_statusIndicator_1ge4x_144",ae="_statusRunning_1ge4x_152",oe="_statusPaused_1ge4x_157",re="_statusNotRunning_1ge4x_161",ne="_statusLabel_1ge4x_165",le="_statusMeta_1ge4x_172",ie="_controlButtons_1ge4x_178",ce="_btn_1ge4x_185",de="_btnPrimary_1ge4x_207",pe="_btnDanger_1ge4x_217",me="_historyList_1ge4x_227",ue="_historyItem_1ge4x_235",he="_historyItemSelected_1ge4x_254",xe="_historyItemHeader_1ge4x_259",ye="_historyIcon_1ge4x_265",_e="_historyTimestamp_1ge4x_270",ge="_historyName_1ge4x_277",ve="_historyItemMeta_1ge4x_287",Se="_historyMode_1ge4x_296",fe="_historyDuration_1ge4x_300",je="_historyStatus_1ge4x_304",be="_status_passed_1ge4x_311",Ne="_status_failed_1ge4x_315",Ce="_status_running_1ge4x_319",we="_historyError_1ge4x_323",Le="_historyContext_1ge4x_333",Ie="_historyContextLine_1ge4x_342",Pe="_historyContextLabel_1ge4x_348",Re="_reportContainer_1ge4x_357",Te="_reportContextPanel_1ge4x_363",Be="_reportContextRow_1ge4x_373",Me="_reportContextLabel_1ge4x_381",ke="_reportSection_1ge4x_389",Ae="_reportSectionHeader_1ge4x_395",He="_reportMarkdown_1ge4x_407",De="_reportLogs_1ge4x_420",Ee="_emptyState_1ge4x_435",Ue="_emptyStateTitle_1ge4x_442",$e="_emptyStateMessage_1ge4x_450",Oe="_upgradePanel_1ge4x_459",Fe="_upgradePanelIcon_1ge4x_467",We="_upgradePanelTitle_1ge4x_472",Ve="_upgradePanelDesc_1ge4x_480",ze="_benefitList_1ge4x_490",Ge="_benefitItem_1ge4x_501",Xe="_upgradeActions_1ge4x_516",s={page:W,sampleBanner:V,sampleBannerMain:z,sampleBadge:G,sampleTitle:X,sampleMessage:Y,sampleActions:Z,primaryAction:q,secondaryAction:J,card:K,cardHeader:Q,clearButton:ee,statusRow:te,statusIndicator:se,statusRunning:ae,statusPaused:oe,statusNotRunning:re,statusLabel:ne,statusMeta:le,controlButtons:ie,btn:ce,btnPrimary:de,btnDanger:pe,historyList:me,historyItem:ue,historyItemSelected:he,historyItemHeader:xe,historyIcon:ye,historyTimestamp:_e,historyName:ge,historyItemMeta:ve,historyMode:Se,historyDuration:fe,historyStatus:je,status_passed:be,status_failed:Ne,status_running:Ce,historyError:we,historyContext:Le,historyContextLine:Ie,historyContextLabel:Pe,reportContainer:Re,reportContextPanel:Te,reportContextRow:Be,reportContextLabel:Me,reportSection:ke,reportSectionHeader:Ae,reportMarkdown:He,reportLogs:De,emptyState:Ee,emptyStateTitle:Ue,emptyStateMessage:$e,upgradePanel:Oe,upgradePanelIcon:Fe,upgradePanelTitle:We,upgradePanelDesc:Ve,benefitList:ze,benefitItem:Ge,upgradeActions:Xe};function g(t){return t.trim().toLowerCase()}function Ye(t){switch(g(t)){case"passed":return"✅";case"failed":return"❌";case"running":return"⏱";default:return"❓"}}function Ze(t,o){switch(g(o)){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 o}}function qe(t,o){switch(g(o)){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 Je(t){return t<1e3?`${t}ms`:`${(t/1e3).toFixed(1)}s`}function Ke({entries:t,onSelect:o,selectedTimestamp:d}){const{t:r}=j();return t.length===0?e.jsx("div",{className:s.emptyState,children:r("playtest.history.empty","No test results yet")}):e.jsx("div",{className:s.historyList,children:t.map(a=>{var p,l,c,m,u,x;const i=a.timestamp===d;return e.jsxs("button",{className:`${s.historyItem} ${i?s.historyItemSelected:""}`,onClick:()=>o(a.timestamp),children:[e.jsxs("div",{className:s.historyItemHeader,children:[e.jsx("span",{className:s.historyIcon,children:Ye(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:r("playtest.history.mode.tooltip","Playtest mode used for this recorded test run."),children:e.jsxs("span",{className:s.historyMode,children:[r("playtest.history.mode","Mode"),": ",Ze(r,a.mode)]})}),e.jsx("span",{className:s.historyDuration,children:Je(a.durationMs)}),e.jsx(_,{text:r("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:qe(r,a.status)})})]}),a.errorMessage&&e.jsx("div",{className:s.historyError,children:a.errorMessage}),(a.contextId||((p=a.contextSummary)==null?void 0:p.testScenario)||((l=a.contextSummary)==null?void 0:l.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:r("playtest.context.contextId","Context ID")}),e.jsx("span",{children:a.contextId})]}),((m=a.contextSummary)==null?void 0:m.testScenario)&&e.jsxs("div",{className:s.historyContextLine,children:[e.jsx("span",{className:s.historyContextLabel,children:r("playtest.context.why","Why this test ran")}),e.jsx("span",{children:a.contextSummary.testScenario})]}),((u=a.contextSummary)==null?void 0:u.expectedBehavior)&&e.jsxs("div",{className:s.historyContextLine,children:[e.jsx("span",{className:s.historyContextLabel,children:r("playtest.context.expected","Expected")}),e.jsx("span",{children:a.contextSummary.expectedBehavior})]}),((x=a.contextSummary)==null?void 0:x.observedBehavior)&&e.jsxs("div",{className:s.historyContextLine,children:[e.jsx("span",{className:s.historyContextLabel,children:r("playtest.context.observed","Observed")}),e.jsx("span",{children:a.contextSummary.observedBehavior})]})]})]},a.timestamp)})})}function Qe({report:t}){var r,a,i,p,l,c;const{t:o}=j(),d=!!((r=t.contextSummary)!=null&&r.testScenario||(a=t.contextSummary)!=null&&a.expectedBehavior||(i=t.contextSummary)!=null&&i.observedBehavior);return e.jsxs("div",{className:s.reportContainer,children:[d&&e.jsxs("div",{className:s.reportContextPanel,children:[((p=t.contextSummary)==null?void 0:p.testScenario)&&e.jsxs("div",{className:s.reportContextRow,children:[e.jsx("span",{className:s.reportContextLabel,children:o("playtest.context.why","Why this test ran")}),e.jsx("span",{children:t.contextSummary.testScenario})]}),((l=t.contextSummary)==null?void 0:l.expectedBehavior)&&e.jsxs("div",{className:s.reportContextRow,children:[e.jsx("span",{className:s.reportContextLabel,children:o("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:o("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:o("playtest.report.content.tooltip","Markdown summary for the selected automated playtest run."),children:e.jsx("span",{children:o("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:o("playtest.report.logs.tooltip","Execution logs captured for the selected automated playtest run."),children:e.jsx("span",{children:o("playtest.report.logs","Logs")})})}),e.jsx("pre",{className:s.reportLogs,children:t.logs})]}),!t.markdown&&!t.logs&&e.jsx("div",{className:s.emptyState,children:o("playtest.report.empty","No report content available")})]})}function ot(){var L;const{t}=j(),{tier:o,loading:d}=H(),r=!d&&o==="basic",a=O({enabled:!r}),{show:i}=A(),[p,l]=n.useState(null),[c,m]=n.useState(!1),[u,x]=n.useState(!1),[v,y]=n.useState(!1),{history:S,selectedReport:R,loading:T}=a,h=r?F(t):null,b=((L=h==null?void 0:h.history[0])==null?void 0:L.timestamp)??null,N=r?p??b:p,C=(h==null?void 0:h.history)??S,w=h&&N===b?h.report:R,B=r?!1:T,M=I=>{l(I),!r&&a.loadReport(I)},k=async()=>{x(!0);try{await a.clearHistory(),i(t("toast.clearSuccess","Cleared successfully"),"success"),m(!1),l(null)}catch{i(t("toast.clearFailed","Failed to clear data"),"error")}finally{x(!1)}};return e.jsxs("div",{className:s.page,children:[r&&e.jsxs("div",{className:s.sampleBanner,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:()=>y(!0),children:t("tier.compare","Basic vs Pro")}),e.jsx("a",{className:s.primaryAction,href:D.playtest,target:"_blank",rel:"noreferrer",children:t("tier.upgrade","Upgrade to Pro")})]})]}),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.")}),r?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:()=>m(!0),children:t("common.clear","Clear")})]}),B?e.jsx("div",{className:s.emptyState,children:t("common.loading","Loading...")}):C.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","WROX 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(Ke,{entries:C,onSelect:M,selectedTimestamp:N??void 0})]}),w&&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(Qe,{report:w})]}),!r&&e.jsx(U,{open:c,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:u,onCancel:()=>!u&&m(!1),onConfirm:k}),v&&e.jsx(E,{onClose:()=>y(!1)})]})}export{ot as Component};
@@ -0,0 +1 @@
1
+ ._page_1ge4x_2{display:flex;flex-direction:column;gap:16px;max-width:900px}._sampleBanner_1ge4x_9{display:flex;align-items:center;justify-content:space-between;gap:20px;padding:18px 20px;border:1px solid var(--pro-border);border-radius:var(--radius);background:linear-gradient(135deg,#f0bd5829,#f0bd5808 55%),var(--bg-card)}._sampleBannerMain_1ge4x_22{display:flex;flex-direction:column;gap:8px;min-width:0}._sampleBadge_1ge4x_29{width:fit-content;padding:0;border-radius:0;background:none;border:none;color:var(--pro-text);font-family:var(--font-label);font-size:11px;font-weight:600;letter-spacing:.02em;text-transform:none;opacity:.92}._sampleTitle_1ge4x_44{font-family:var(--font-label);font-size:16px;font-weight:600;color:var(--text-primary)}._sampleMessage_1ge4x_51{max-width:560px;color:var(--text-secondary);font-size:13px;line-height:1.5}._sampleActions_1ge4x_58{display:flex;align-items:center;gap:8px;flex-wrap:wrap;justify-content:flex-end}._primaryAction_1ge4x_66,._secondaryAction_1ge4x_67{display:inline-flex;align-items:center;justify-content:center;min-height:34px;padding:0 14px;border-radius:8px;font-family:var(--font-label);font-size:12px;text-decoration:none;transition:background var(--transition),border-color var(--transition),opacity var(--transition)}._secondaryAction_1ge4x_67{border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-primary);cursor:pointer}._secondaryAction_1ge4x_67:hover{border-color:var(--accent);background:var(--accent-dim)}._primaryAction_1ge4x_66{border:1px solid var(--pro-badge);background:var(--pro-badge);color:#1a1407}._primaryAction_1ge4x_66:hover{opacity:.9}._card_1ge4x_103{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:16px 20px}._cardHeader_1ge4x_110{font-family:var(--font-label);font-size:13px;font-weight:600;color:var(--text-primary);margin-bottom:12px;display:flex;align-items:center;justify-content:space-between;gap:8px}._clearButton_1ge4x_122{border:1px solid rgba(209,84,84,.5);background:#d154541f;color:#f4c1c1;border-radius:8px;padding:6px 12px;cursor:pointer}._clearButton_1ge4x_122:disabled{cursor:not-allowed;opacity:.55}._statusRow_1ge4x_137{display:flex;align-items:center;gap:12px;margin-bottom:8px}._statusIndicator_1ge4x_144{display:inline-block;width:8px;height:8px;border-radius:50%;flex-shrink:0}._statusRunning_1ge4x_152{background:var(--success);box-shadow:0 0 6px var(--success)}._statusPaused_1ge4x_157{background:var(--warning)}._statusNotRunning_1ge4x_161{background:var(--text-muted)}._statusLabel_1ge4x_165{font-family:var(--font-code);font-size:13px;font-weight:600;color:var(--text-primary)}._statusMeta_1ge4x_172{font-family:var(--font-code);font-size:12px;color:var(--text-secondary)}._controlButtons_1ge4x_178{display:flex;gap:8px;margin-top:12px}._btn_1ge4x_185{font-family:var(--font-label);font-size:12px;padding:6px 14px;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_1ge4x_185:hover{border-color:var(--accent);background:var(--accent-dim)}._btn_1ge4x_185:disabled{opacity:.4;pointer-events:none}._btnPrimary_1ge4x_207{background:var(--accent);color:var(--bg-card);border-color:var(--accent)}._btnPrimary_1ge4x_207:hover{opacity:.9}._btnDanger_1ge4x_217{border-color:var(--error);color:var(--error)}._btnDanger_1ge4x_217:hover{background:#ef44441a}._historyList_1ge4x_227{display:flex;flex-direction:column;gap:4px;max-height:320px;overflow-y:auto}._historyItem_1ge4x_235{display:flex;flex-direction:column;gap:4px;padding:8px 12px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg-card);cursor:pointer;text-align:left;width:100%;font-family:inherit;transition:border-color var(--transition)}._historyItem_1ge4x_235:hover{border-color:var(--accent)}._historyItemSelected_1ge4x_254{border-color:var(--accent);background:var(--accent-dim)}._historyItemHeader_1ge4x_259{display:flex;align-items:center;gap:8px}._historyIcon_1ge4x_265{font-size:14px;flex-shrink:0}._historyTimestamp_1ge4x_270{font-family:var(--font-code);font-size:11px;color:var(--text-muted);flex-shrink:0}._historyName_1ge4x_277{font-family:var(--font-label);font-size:12px;font-weight:500;color:var(--text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._historyItemMeta_1ge4x_287{display:flex;gap:12px;font-family:var(--font-code);font-size:11px;color:var(--text-secondary);padding-left:22px}._historyMode_1ge4x_296{color:var(--text-muted)}._historyDuration_1ge4x_300{color:var(--text-secondary)}._historyStatus_1ge4x_304{font-weight:500;text-transform:uppercase;font-size:10px;letter-spacing:.04em}._status_passed_1ge4x_311{color:var(--success)}._status_failed_1ge4x_315{color:var(--error)}._status_running_1ge4x_319{color:var(--accent)}._historyError_1ge4x_323{font-family:var(--font-code);font-size:11px;color:var(--error);padding-left:22px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._historyContext_1ge4x_333{display:flex;flex-direction:column;gap:4px;padding-left:22px;color:var(--text-secondary);font-size:11px}._historyContextLine_1ge4x_342{display:flex;flex-direction:column;gap:2px}._historyContextLabel_1ge4x_348{font-family:var(--font-label);font-size:10px;color:var(--text-muted);text-transform:uppercase;letter-spacing:.05em}._reportContainer_1ge4x_357{display:flex;flex-direction:column;gap:12px}._reportContextPanel_1ge4x_363{display:flex;flex-direction:column;gap:10px;padding:12px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg-secondary)}._reportContextRow_1ge4x_373{display:flex;flex-direction:column;gap:4px;color:var(--text-primary);font-size:12px}._reportContextLabel_1ge4x_381{font-family:var(--font-label);font-size:10px;color:var(--text-muted);text-transform:uppercase;letter-spacing:.05em}._reportSection_1ge4x_389{border:1px solid var(--border);border-radius:var(--radius);overflow:hidden}._reportSectionHeader_1ge4x_395{font-family:var(--font-label);font-size:11px;font-weight:600;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.06em;padding:6px 12px;background:var(--bg-secondary);border-bottom:1px solid var(--border)}._reportMarkdown_1ge4x_407{padding:12px;margin:0;font-family:var(--font-code);font-size:12px;line-height:1.6;color:var(--text-primary);white-space:pre-wrap;word-break:break-word;max-height:400px;overflow-y:auto}._reportLogs_1ge4x_420{padding:12px;margin:0;font-family:var(--font-code);font-size:11px;line-height:1.5;color:var(--text-secondary);white-space:pre-wrap;word-break:break-word;max-height:240px;overflow-y:auto;background:var(--bg-secondary)}._emptyState_1ge4x_435{text-align:center;padding:32px 16px;color:var(--text-muted);font-size:13px}._emptyStateTitle_1ge4x_442{font-family:var(--font-label);font-size:14px;font-weight:600;color:var(--text-secondary);margin-bottom:8px}._emptyStateMessage_1ge4x_450{font-size:12px;color:var(--text-muted);max-width:360px;margin:0 auto;line-height:1.5}._upgradePanel_1ge4x_459{background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius);padding:32px 24px;text-align:center}._upgradePanelIcon_1ge4x_467{font-size:32px;margin-bottom:12px}._upgradePanelTitle_1ge4x_472{font-family:var(--font-label);font-size:15px;font-weight:600;color:var(--text-primary);margin-bottom:8px}._upgradePanelDesc_1ge4x_480{font-size:13px;color:var(--text-secondary);margin-bottom:16px;max-width:400px;margin-left:auto;margin-right:auto;line-height:1.5}._benefitList_1ge4x_490{list-style:none;padding:0;margin:0 auto 16px;display:flex;flex-direction:column;gap:4px;max-width:360px;text-align:left}._benefitItem_1ge4x_501{font-size:12px;color:var(--text-secondary);padding-left:16px;position:relative}._benefitItem_1ge4x_501:before{content:"+";position:absolute;left:0;color:var(--accent);font-weight:600}._upgradeActions_1ge4x_516{display:flex;gap:8px;justify-content:center}@media(max-width:720px){._sampleBanner_1ge4x_9{flex-direction:column;align-items:stretch}._sampleActions_1ge4x_58{justify-content:stretch}._primaryAction_1ge4x_66,._secondaryAction_1ge4x_67{width:100%}}
@@ -1,4 +1,4 @@
1
- import{u as f,r as h,j as n}from"./index-CkXvRg-O.js";const _="_container_uv8oc_2",p="_header_uv8oc_10",N="_modeBtn_uv8oc_18",x="_modeBtnActive_uv8oc_33",v="_unifiedView_uv8oc_40",j="_diffLine_uv8oc_46",y="_lineNum_uv8oc_55",g="_lineContent_uv8oc_64",C="_lineAdded_uv8oc_68",B="_lineRemoved_uv8oc_73",V="_lineContext_uv8oc_78",w="_sideBySide_uv8oc_83",L="_sidePane_uv8oc_90",$="_sideLabel_uv8oc_100",b="_sideContent_uv8oc_112",A="_empty_uv8oc_117",e={container:_,header:p,modeBtn:N,modeBtnActive:x,unifiedView:v,diffLine:j,lineNum:y,lineContent:g,lineAdded:C,lineRemoved:B,lineContext:V,sideBySide:w,sidePane:L,sideLabel:$,sideContent:b,empty:A};function S(t,c){const d=t.split(`
1
+ import{u as f,r as h,j as n}from"./index-DWRH2iF4.js";const _="_container_uv8oc_2",p="_header_uv8oc_10",N="_modeBtn_uv8oc_18",x="_modeBtnActive_uv8oc_33",v="_unifiedView_uv8oc_40",j="_diffLine_uv8oc_46",y="_lineNum_uv8oc_55",g="_lineContent_uv8oc_64",C="_lineAdded_uv8oc_68",B="_lineRemoved_uv8oc_73",V="_lineContext_uv8oc_78",w="_sideBySide_uv8oc_83",L="_sidePane_uv8oc_90",$="_sideLabel_uv8oc_100",b="_sideContent_uv8oc_112",A="_empty_uv8oc_117",e={container:_,header:p,modeBtn:N,modeBtnActive:x,unifiedView:v,diffLine:j,lineNum:y,lineContent:g,lineAdded:C,lineRemoved:B,lineContext:V,sideBySide:w,sidePane:L,sideLabel:$,sideContent:b,empty:A};function S(t,c){const d=t.split(`
2
2
  `),l=c.split(`
3
3
  `),a=[],m=Math.max(d.length,l.length);let s=0,i=0;for(;(s<d.length||i<l.length)&&(s<d.length&&i<l.length?d[s]===l[i]?(a.push({type:"context",content:d[s],lineNum:i+1}),s++,i++):(a.push({type:"removed",content:d[s],lineNum:s+1}),s++,s<d.length&&d[s]===l[i]?(a.push({type:"added",content:l[i],lineNum:i+1}),i++):i<l.length&&(a.push({type:"added",content:l[i],lineNum:i+1}),i++)):s<d.length?(a.push({type:"removed",content:d[s],lineNum:s+1}),s++):i<l.length&&(a.push({type:"added",content:l[i],lineNum:i+1}),i++),!(a.length>m*3)););return a}function E({before:t,after:c}){const{t:d}=f(),[l,a]=h.useState("unified"),m=h.useMemo(()=>S(t??"",c??""),[t,c]);if(!t&&!c)return n.jsx("div",{className:e.container,children:n.jsx("div",{className:e.empty,children:d("changelog.diff.empty","No diff available")})});if(!t&&c){const s=c.split(`
4
4
  `);return n.jsx("div",{className:e.container,children:n.jsx("div",{className:e.unifiedView,children:s.map((i,u)=>n.jsxs("div",{className:`${e.diffLine} ${e.lineAdded}`,children:[n.jsx("span",{className:e.lineNum,children:u+1}),n.jsxs("span",{className:e.lineContent,children:["+ ",i]})]},u))})})}return n.jsxs("div",{className:e.container,children:[n.jsxs("div",{className:e.header,children:[n.jsx("button",{className:`${e.modeBtn} ${l==="unified"?e.modeBtnActive:""}`,onClick:()=>a("unified"),children:d("changelog.diff.unified","Unified")}),n.jsx("button",{className:`${e.modeBtn} ${l==="side-by-side"?e.modeBtnActive:""}`,onClick:()=>a("side-by-side"),children:d("changelog.diff.sideBySide","Side by Side")})]}),l==="unified"?n.jsx("div",{className:e.unifiedView,children:m.map((s,i)=>n.jsxs("div",{className:`${e.diffLine} ${s.type==="added"?e.lineAdded:s.type==="removed"?e.lineRemoved:e.lineContext}`,children:[n.jsx("span",{className:e.lineNum,children:s.lineNum??""}),n.jsxs("span",{className:e.lineContent,children:[s.type==="added"?"+ ":s.type==="removed"?"- ":" ",s.content]})]},i))}):n.jsxs("div",{className:e.sideBySide,children:[n.jsxs("div",{className:e.sidePane,children:[n.jsx("div",{className:e.sideLabel,children:d("changelog.diff.before","Before")}),n.jsx("div",{className:e.sideContent,children:(t??"").split(`