@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.
- package/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +19 -1
- package/COMMERCIAL-LICENSE.md +1 -1
- package/README.md +12 -12
- package/TRADEMARKS.md +1 -1
- package/docs/assets/screenshots/plugin_main.png +0 -0
- package/docs/assets/screenshots/plugins_menu.png +0 -0
- package/docs/assets/screenshots/weppy_plugin_toolbar.png +0 -0
- package/docs/en/dashboard/changelog.md +1 -1
- package/docs/en/dashboard/connection.md +1 -1
- package/docs/en/dashboard/overview.md +1 -1
- package/docs/en/dashboard/playtest.md +1 -1
- package/docs/en/dashboard/settings.md +1 -1
- package/docs/en/dashboard/sync.md +1 -1
- package/docs/en/dashboard/tools.md +1 -1
- package/docs/en/installation/README.md +5 -3
- package/docs/en/installation/ai-apps/antigravity.md +1 -1
- package/docs/en/installation/ai-apps/claude-app.md +1 -1
- package/docs/en/installation/ai-apps/claude-code.md +1 -1
- package/docs/en/installation/ai-apps/codex-app.md +1 -1
- package/docs/en/installation/ai-apps/codex-cli.md +1 -1
- package/docs/en/installation/ai-apps/cursor.md +1 -1
- package/docs/en/installation/ai-apps/gemini-cli.md +1 -1
- package/docs/en/installation/roblox-explorer.md +9 -9
- package/docs/en/installation/roblox-plugin.md +3 -3
- package/docs/en/pro-upgrade.md +3 -3
- package/docs/en/sync/overview.md +2 -2
- package/docs/en/tools/system-and-debugging.md +8 -0
- package/docs/es/README.md +7 -7
- package/docs/es/dashboard/changelog.md +1 -1
- package/docs/es/dashboard/connection.md +1 -1
- package/docs/es/dashboard/overview.md +1 -1
- package/docs/es/dashboard/playtest.md +1 -1
- package/docs/es/dashboard/settings.md +1 -1
- package/docs/es/dashboard/sync.md +1 -1
- package/docs/es/dashboard/tools.md +1 -1
- package/docs/es/installation/README.md +2 -2
- package/docs/es/installation/ai-apps/antigravity.md +1 -1
- package/docs/es/installation/ai-apps/claude-app.md +1 -1
- package/docs/es/installation/ai-apps/claude-code.md +1 -1
- package/docs/es/installation/ai-apps/codex-app.md +1 -1
- package/docs/es/installation/ai-apps/codex-cli.md +1 -1
- package/docs/es/installation/ai-apps/cursor.md +1 -1
- package/docs/es/installation/ai-apps/gemini-cli.md +1 -1
- package/docs/es/installation/roblox-explorer.md +9 -9
- package/docs/es/installation/roblox-plugin.md +3 -3
- package/docs/es/pro-upgrade.md +1 -1
- package/docs/es/sync/overview.md +2 -2
- package/docs/es/tools/system-and-debugging.md +8 -0
- package/docs/id/README.md +7 -7
- package/docs/id/dashboard/changelog.md +1 -1
- package/docs/id/dashboard/connection.md +1 -1
- package/docs/id/dashboard/overview.md +1 -1
- package/docs/id/dashboard/playtest.md +1 -1
- package/docs/id/dashboard/settings.md +1 -1
- package/docs/id/dashboard/sync.md +1 -1
- package/docs/id/dashboard/tools.md +1 -1
- package/docs/id/installation/README.md +3 -3
- package/docs/id/installation/ai-apps/antigravity.md +1 -1
- package/docs/id/installation/ai-apps/claude-app.md +1 -1
- package/docs/id/installation/ai-apps/claude-code.md +1 -1
- package/docs/id/installation/ai-apps/codex-app.md +1 -1
- package/docs/id/installation/ai-apps/codex-cli.md +1 -1
- package/docs/id/installation/ai-apps/cursor.md +1 -1
- package/docs/id/installation/ai-apps/gemini-cli.md +1 -1
- package/docs/id/installation/roblox-explorer.md +9 -9
- package/docs/id/installation/roblox-plugin.md +3 -3
- package/docs/id/pro-upgrade.md +1 -1
- package/docs/id/sync/overview.md +2 -2
- package/docs/id/tools/system-and-debugging.md +8 -0
- package/docs/ja/README.md +7 -7
- package/docs/ja/installation/README.md +3 -3
- package/docs/ja/installation/ai-apps/antigravity.md +1 -1
- package/docs/ja/installation/ai-apps/claude-app.md +1 -1
- package/docs/ja/installation/ai-apps/claude-code.md +1 -1
- package/docs/ja/installation/ai-apps/codex-app.md +1 -1
- package/docs/ja/installation/ai-apps/codex-cli.md +1 -1
- package/docs/ja/installation/ai-apps/cursor.md +1 -1
- package/docs/ja/installation/ai-apps/gemini-cli.md +1 -1
- package/docs/ja/installation/roblox-explorer.md +9 -9
- package/docs/ja/installation/roblox-plugin.md +3 -3
- package/docs/ja/pro-upgrade.md +1 -1
- package/docs/ja/sync/overview.md +2 -2
- package/docs/ja/tools/system-and-debugging.md +8 -0
- package/docs/ko/README.md +7 -7
- package/docs/ko/installation/README.md +5 -3
- package/docs/ko/installation/ai-apps/antigravity.md +1 -1
- package/docs/ko/installation/ai-apps/claude-app.md +1 -1
- package/docs/ko/installation/ai-apps/claude-code.md +1 -1
- package/docs/ko/installation/ai-apps/codex-app.md +1 -1
- package/docs/ko/installation/ai-apps/codex-cli.md +1 -1
- package/docs/ko/installation/ai-apps/cursor.md +1 -1
- package/docs/ko/installation/ai-apps/gemini-cli.md +1 -1
- package/docs/ko/installation/roblox-explorer.md +9 -9
- package/docs/ko/installation/roblox-plugin.md +3 -3
- package/docs/ko/pro-upgrade.md +1 -1
- package/docs/ko/sync/overview.md +2 -2
- package/docs/ko/tools/system-and-debugging.md +8 -0
- package/docs/pt-br/README.md +8 -8
- package/docs/pt-br/dashboard/changelog.md +1 -1
- package/docs/pt-br/dashboard/connection.md +1 -1
- package/docs/pt-br/dashboard/overview.md +1 -1
- package/docs/pt-br/dashboard/playtest.md +1 -1
- package/docs/pt-br/dashboard/settings.md +1 -1
- package/docs/pt-br/dashboard/sync.md +1 -1
- package/docs/pt-br/dashboard/tools.md +1 -1
- package/docs/pt-br/installation/README.md +3 -3
- package/docs/pt-br/installation/ai-apps/antigravity.md +1 -1
- package/docs/pt-br/installation/ai-apps/claude-app.md +1 -1
- package/docs/pt-br/installation/ai-apps/claude-code.md +1 -1
- package/docs/pt-br/installation/ai-apps/codex-app.md +1 -1
- package/docs/pt-br/installation/ai-apps/codex-cli.md +1 -1
- package/docs/pt-br/installation/ai-apps/cursor.md +1 -1
- package/docs/pt-br/installation/ai-apps/gemini-cli.md +1 -1
- package/docs/pt-br/installation/roblox-explorer.md +9 -9
- package/docs/pt-br/installation/roblox-plugin.md +3 -3
- package/docs/pt-br/pro-upgrade.md +1 -1
- package/docs/pt-br/sync/overview.md +2 -2
- package/docs/pt-br/tools/system-and-debugging.md +8 -0
- package/docs/troubleshooting.md +1 -1
- package/install.ps1 +37 -14
- package/install.sh +38 -3
- package/llms-full.txt +8 -8
- package/llms.txt +5 -5
- package/package.json +1 -1
- package/plugins/weppy-roblox-mcp/.claude-plugin/plugin.json +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogDetailPage-D6Tqz7ut.css +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogDetailPage-DRPIGDB0.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogPage-BH87M2hn.css +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogPage-DVPYTw2L.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ConfirmModal-CvXLNYq0.js → ConfirmModal-Db4rfrTo.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ConnectionPage-Cv2i3LSr.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{InfoLabel-vz7vtbbV.js → InfoLabel-DzXzzs6Q.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/OverviewPage-Dsfl-NRT.css +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/OverviewPage-FoC28UL8.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/PlaytestPage-BjBAsHLz.js +11 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/PlaytestPage-Dw8nj399.css +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{PropertyDiff-CbDafceC.js → PropertyDiff-BZMdMzMr.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SettingsPage-BB7-WAMU.css +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SettingsPage-BKp2VKMW.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{StatusBadge-BMTgkxDJ.js → StatusBadge-DtcYlxe-.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SyncPage-DcELF5_j.js +4 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromo-CcQarFkP.css +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromo.module-BBX3CVXn.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromoProgress-r5fgmYI5.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ToolsPage-Cfau3bX3.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/index-DWRH2iF4.js +129 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{tier-promo-config-CJ-J0n2q.css → tier-promo-config-C-Xy3iYW.css} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{tier-promo-config-B9lIKWCQ.js → tier-promo-config-CQFDWwo4.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{useLiveUptime-DXXyWm6j.js → useLiveUptime-5lD1XKnw.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/index.html +3 -3
- package/plugins/weppy-roblox-mcp/dashboard/dist/wrox-icon.png +0 -0
- package/plugins/weppy-roblox-mcp/dist/index.js +79 -76
- package/plugins/weppy-roblox-mcp/roblox-plugin/WeppyRobloxMCP.rbxm +0 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogDetailPage-C2oKsYGC.css +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogDetailPage-IgHLnaEX.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogPage-Br-A5H5t.css +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogPage-Dao4jPQA.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ConnectionPage-Bl7tLgL2.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/OverviewPage-BDDctbAl.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/OverviewPage-CS05LsEh.css +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/PlaytestPage-C0iCoAQp.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/PlaytestPage-LnuHE5FL.css +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SettingsPage-CJs9ctOf.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SettingsPage-DP9OFhNb.css +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SyncPage-BfXIBNVS.js +0 -4
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromoPanel-CUrTMsXB.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromoProgress-DBA-FZGE.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ToolsPage-O4dXhEU-.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/index-CkXvRg-O.js +0 -69
- 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.
|
package/docs/troubleshooting.md
CHANGED
|
@@ -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 →
|
|
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
|
-
#
|
|
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 "
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
#
|
|
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}
|
|
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}
|
|
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
|
-
#
|
|
1
|
+
# WROX — Full Documentation
|
|
2
2
|
|
|
3
|
-
>
|
|
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
|
+
> 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 **
|
|
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 -> **
|
|
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 **
|
|
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
|
|
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 →
|
|
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
|
-
#
|
|
1
|
+
# WROX — MCP Server for Roblox Studio
|
|
2
2
|
|
|
3
|
-
>
|
|
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
|
-
|
|
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
|
-
-
|
|
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.
|
|
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",
|
|
@@ -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-
|
|
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,
|
|
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-
|
|
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(`
|