@weppy/roblox-mcp 2.1.0 → 2.1.2
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 +16 -0
- package/docs/assets/screenshots/plugin/sync/sync-main.png +0 -0
- package/install.ps1 +164 -22
- package/install.sh +82 -9
- 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-lzDR6yjY.js → ChangelogDetailPage-2ZPwh_Le.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogPage-DW2_STiE.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ConfirmModal-BIJpNntn.js → ConfirmModal-CInBBLZW.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ConnectionPage-CdLqNY4r.js → ConnectionPage-nNwPIEZw.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{InfoLabel-CBAqTqRy.js → InfoLabel-B_Ys60mi.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/OverviewPage-BMBzDR4R.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/PlaytestPage-BDgsWgto.js +11 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/PlaytestPage-CYSu0pfO.css +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{PropertyDiff-D34Apw3G.js → PropertyDiff-BbsF9z4D.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{SettingsPage-yWzPPZIB.js → SettingsPage-BPSAA3lu.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{StatusBadge-B-pYMpUG.js → StatusBadge-FYpJOX7r.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{SyncPage-E4XZhZn0.js → SyncPage-BcXYv0GI.js} +2 -2
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierComparison-D4uVUGcZ.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierComparison-DGh9vLz0.css +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromo-D5n9OoEm.css +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromo.module-CAoUYgIx.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromoProgress-Cuz1dgcs.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ToolsPage-YGBoDwbQ.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{index-E1cuNPsJ.js → index-BNdn6WpU.js} +18 -18
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{useLiveUptime-qJDofPOo.js → useLiveUptime-D5Ux8dA5.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/index.html +1 -1
- package/plugins/weppy-roblox-mcp/dist/index.js +4 -4
- package/plugins/weppy-roblox-mcp/roblox-plugin/WeppyRobloxMCP.rbxm +0 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogPage-BscI67Aj.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/OverviewPage-BOm0Ai9y.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/PlaytestPage-DaDbQ6Qa.js +0 -11
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/PlaytestPage-Dw8nj399.css +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromo-CcQarFkP.css +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromo.module-BBX3CVXn.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromoProgress-CqxKoPOJ.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ToolsPage-yaahWgTq.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/tier-promo-config-BuGSENUv.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/tier-promo-config-C-Xy3iYW.css +0 -1
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Weppy Roblox MCP — MCP server that lets AI coding agents control a live Roblox Studio session with 21 tools, 140+ actions, bidirectional sync, automated playtest, and multi-place support",
|
|
9
|
-
"version": "2.1.
|
|
9
|
+
"version": "2.1.2"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "weppy-roblox-mcp",
|
|
14
14
|
"source": "./plugins/weppy-roblox-mcp",
|
|
15
15
|
"description": "Weppy Roblox MCP — MCP server that lets AI coding agents control a live Roblox Studio session with 21 tools, 140+ actions, bidirectional sync, automated playtest, and multi-place support",
|
|
16
|
-
"version": "2.1.
|
|
16
|
+
"version": "2.1.2",
|
|
17
17
|
"author": {
|
|
18
18
|
"name": "hope1026"
|
|
19
19
|
},
|
package/CHANGELOG.md
CHANGED
|
@@ -21,6 +21,22 @@ All notable changes to this project will be documented in this file.
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
## [2.1.2] - 2026-03-31
|
|
29
|
+
|
|
30
|
+
### Stability Improvements
|
|
31
|
+
|
|
32
|
+
- Improve overall system stability and reliability
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
## [2.1.1] - 2026-03-29
|
|
36
|
+
|
|
37
|
+
### Bug Fixes
|
|
38
|
+
|
|
39
|
+
- fix Windows install script (`install.ps1`) to resolve `npm.cmd` execution policy issues by introducing `Invoke-Npm` wrapper
|
|
24
40
|
|
|
25
41
|
|
|
26
42
|
## [2.1.0] - 2026-03-29
|
|
Binary file
|
package/install.ps1
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
$ErrorActionPreference = "Stop"
|
|
14
14
|
$script:InstallLogPath = Join-Path ([System.IO.Path]::GetTempPath()) ("wrox-install-{0:yyyyMMdd-HHmmss}.log" -f (Get-Date))
|
|
15
15
|
$script:TranscriptStarted = $false
|
|
16
|
+
$script:NpmCommandPath = $null
|
|
17
|
+
$script:NpmGlobalPrefix = $null
|
|
16
18
|
|
|
17
19
|
# ── Utilities ──
|
|
18
20
|
function Write-Step($step, $msg) { Write-Host "`n[$step] $msg" -ForegroundColor Cyan -NoNewline; Write-Host "" }
|
|
@@ -53,6 +55,98 @@ function Confirm-Action($prompt) {
|
|
|
53
55
|
return $reply -match '^[Yy]'
|
|
54
56
|
}
|
|
55
57
|
|
|
58
|
+
function Resolve-NpmCommand() {
|
|
59
|
+
if ($script:NpmCommandPath) {
|
|
60
|
+
return $script:NpmCommandPath
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
$npmCommand = Get-Command npm.cmd -ErrorAction SilentlyContinue
|
|
64
|
+
if (-not $npmCommand) {
|
|
65
|
+
Abort-Install "npm.cmd not found. Check Node.js installation."
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
$script:NpmCommandPath = $npmCommand.Source
|
|
69
|
+
return $script:NpmCommandPath
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function Get-NpmGlobalPrefix() {
|
|
73
|
+
if ($script:NpmGlobalPrefix) {
|
|
74
|
+
return $script:NpmGlobalPrefix
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
$script:NpmGlobalPrefix = (Invoke-Npm prefix -g 2>$null | Out-String).Trim()
|
|
78
|
+
return $script:NpmGlobalPrefix
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function Invoke-Npm {
|
|
82
|
+
param(
|
|
83
|
+
[Parameter(ValueFromRemainingArguments = $true)]
|
|
84
|
+
[string[]]$Args
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
$npmCommandPath = Resolve-NpmCommand
|
|
88
|
+
$output = & $npmCommandPath @Args
|
|
89
|
+
if ($LASTEXITCODE -ne 0) {
|
|
90
|
+
throw "npm $($Args -join ' ') failed with exit code $LASTEXITCODE"
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return $output
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function Resolve-OptionalCliCommand($commandName) {
|
|
97
|
+
$resolvedCommand = Get-Command $commandName -ErrorAction SilentlyContinue
|
|
98
|
+
if ($resolvedCommand) {
|
|
99
|
+
return $resolvedCommand.Source
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
$candidatePaths = @()
|
|
103
|
+
$npmPrefix = Get-NpmGlobalPrefix
|
|
104
|
+
if ($npmPrefix) {
|
|
105
|
+
$candidatePaths += (Join-Path $npmPrefix "$commandName.cmd")
|
|
106
|
+
$candidatePaths += (Join-Path $npmPrefix $commandName)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if ($env:APPDATA) {
|
|
110
|
+
$appDataNpmDir = Join-Path $env:APPDATA 'npm'
|
|
111
|
+
$candidatePaths += (Join-Path $appDataNpmDir "$commandName.cmd")
|
|
112
|
+
$candidatePaths += (Join-Path $appDataNpmDir $commandName)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
foreach ($candidatePath in $candidatePaths) {
|
|
116
|
+
if ([string]::IsNullOrWhiteSpace($candidatePath)) {
|
|
117
|
+
continue
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (Test-Path $candidatePath) {
|
|
121
|
+
return $candidatePath
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return $null
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function Test-McpJsonConfigured($configPath) {
|
|
129
|
+
if (-not (Test-Path $configPath)) {
|
|
130
|
+
return $false
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
try {
|
|
134
|
+
$config = Get-Content -Path $configPath -Raw | ConvertFrom-Json
|
|
135
|
+
return $null -ne $config.mcpServers.'weppy-roblox-mcp'
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
return $false
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function Test-CodexConfigConfigured($configPath) {
|
|
143
|
+
if (-not (Test-Path $configPath)) {
|
|
144
|
+
return $false
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return Select-String -Path $configPath -Pattern '^\s*\[mcp_servers\.weppy-roblox-mcp\]\s*$' -Quiet
|
|
148
|
+
}
|
|
149
|
+
|
|
56
150
|
# Add MCP server to JSON config file (PowerShell 5.1 compatible — edits JSON via node)
|
|
57
151
|
function Add-McpToConfig($configPath) {
|
|
58
152
|
$parentDir = Split-Path $configPath -Parent
|
|
@@ -104,7 +198,7 @@ Write-Step "1/3" "Install @weppy/roblox-mcp via npm"
|
|
|
104
198
|
|
|
105
199
|
if (Confirm-Action " Run npm install -g @weppy/roblox-mcp?") {
|
|
106
200
|
try {
|
|
107
|
-
|
|
201
|
+
Invoke-Npm install -g "@weppy/roblox-mcp"
|
|
108
202
|
Write-Ok "Installed @weppy/roblox-mcp"
|
|
109
203
|
}
|
|
110
204
|
catch {
|
|
@@ -124,7 +218,7 @@ $pluginsDir = Join-Path $env:LOCALAPPDATA "Roblox\Plugins"
|
|
|
124
218
|
$pluginName = "WeppyRobloxMCP.rbxm"
|
|
125
219
|
|
|
126
220
|
# Search for .rbxm in npm global path
|
|
127
|
-
$npmPrefix =
|
|
221
|
+
$npmPrefix = Get-NpmGlobalPrefix
|
|
128
222
|
$bundledPlugin = $null
|
|
129
223
|
$searchPaths = @(
|
|
130
224
|
(Join-Path $npmPrefix "node_modules\@weppy\roblox-mcp\plugins\weppy-roblox-mcp\roblox-plugin\$pluginName"),
|
|
@@ -170,13 +264,21 @@ $detectedNames = @()
|
|
|
170
264
|
$detectedTypes = @()
|
|
171
265
|
$notDetected = @()
|
|
172
266
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
267
|
+
$claudeProjectConfig = Join-Path (Get-Location).Path '.mcp.json'
|
|
268
|
+
$claudeGlobalConfig = Join-Path $env:USERPROFILE '.claude\mcp.json'
|
|
269
|
+
$claudeCodeConfigured = (Test-McpJsonConfigured $claudeProjectConfig) -or (Test-McpJsonConfigured $claudeGlobalConfig)
|
|
270
|
+
$claudeCodeCliCommand = Resolve-OptionalCliCommand 'claude'
|
|
271
|
+
|
|
272
|
+
if ($claudeCodeConfigured) {
|
|
273
|
+
$detectedNames += 'Claude Code (configured)'
|
|
274
|
+
$detectedTypes += 'claude-code'
|
|
275
|
+
}
|
|
276
|
+
elseif ($claudeCodeCliCommand) {
|
|
277
|
+
$detectedNames += 'Claude Code (CLI)'
|
|
278
|
+
$detectedTypes += 'claude-code'
|
|
177
279
|
}
|
|
178
280
|
else {
|
|
179
|
-
$notDetected +=
|
|
281
|
+
$notDetected += 'Claude Code (not found)'
|
|
180
282
|
}
|
|
181
283
|
|
|
182
284
|
# Claude Desktop
|
|
@@ -199,17 +301,32 @@ else {
|
|
|
199
301
|
$notDetected += "Cursor (not found)"
|
|
200
302
|
}
|
|
201
303
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
304
|
+
$codexConfig = Join-Path $env:USERPROFILE '.codex\config.toml'
|
|
305
|
+
$codexConfigured = Test-CodexConfigConfigured $codexConfig
|
|
306
|
+
$codexCliCommand = Resolve-OptionalCliCommand 'codex'
|
|
307
|
+
|
|
308
|
+
if ($codexConfigured) {
|
|
309
|
+
$detectedNames += 'Codex CLI (configured)'
|
|
310
|
+
$detectedTypes += 'codex-cli'
|
|
311
|
+
}
|
|
312
|
+
elseif ($codexCliCommand) {
|
|
313
|
+
$detectedNames += 'Codex CLI'
|
|
314
|
+
$detectedTypes += 'codex-cli'
|
|
206
315
|
}
|
|
207
316
|
else {
|
|
208
|
-
$notDetected +=
|
|
317
|
+
$notDetected += 'Codex CLI (not found)'
|
|
209
318
|
}
|
|
210
319
|
|
|
211
320
|
# Gemini CLI
|
|
212
|
-
|
|
321
|
+
$geminiConfig = Join-Path $env:USERPROFILE '.gemini\settings.json'
|
|
322
|
+
$geminiConfigured = Test-McpJsonConfigured $geminiConfig
|
|
323
|
+
$geminiCliCommand = Resolve-OptionalCliCommand 'gemini'
|
|
324
|
+
|
|
325
|
+
if ($geminiConfigured) {
|
|
326
|
+
$detectedNames += 'Gemini CLI (configured)'
|
|
327
|
+
$detectedTypes += "gemini-cli"
|
|
328
|
+
}
|
|
329
|
+
elseif ($geminiCliCommand) {
|
|
213
330
|
$detectedNames += "Gemini CLI"
|
|
214
331
|
$detectedTypes += "gemini-cli"
|
|
215
332
|
}
|
|
@@ -264,8 +381,19 @@ else {
|
|
|
264
381
|
try {
|
|
265
382
|
switch ($appType) {
|
|
266
383
|
"claude-code" {
|
|
267
|
-
|
|
268
|
-
|
|
384
|
+
if ($claudeCodeConfigured) {
|
|
385
|
+
Write-Ok "Already configured: $appName"
|
|
386
|
+
}
|
|
387
|
+
elseif ($claudeCodeCliCommand) {
|
|
388
|
+
& $claudeCodeCliCommand mcp add weppy-roblox-mcp -- npx -y "@weppy/roblox-mcp"
|
|
389
|
+
if ($LASTEXITCODE -ne 0) {
|
|
390
|
+
throw 'claude mcp add failed'
|
|
391
|
+
}
|
|
392
|
+
Write-Ok "Registered: $appName"
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
Write-Fail "Failed: $appName (CLI/config unavailable)"
|
|
396
|
+
}
|
|
269
397
|
}
|
|
270
398
|
"claude-desktop" {
|
|
271
399
|
Add-McpToConfig $claudeDesktopConfig
|
|
@@ -277,15 +405,29 @@ else {
|
|
|
277
405
|
Write-Ok "Registered: $appName"
|
|
278
406
|
}
|
|
279
407
|
"codex-cli" {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
408
|
+
if ($codexConfigured) {
|
|
409
|
+
Write-Ok "Already configured: $appName"
|
|
410
|
+
}
|
|
411
|
+
elseif ($codexCliCommand) {
|
|
412
|
+
try { & $codexCliCommand mcp remove weppy-roblox-mcp *> $null } catch {}
|
|
413
|
+
& $codexCliCommand mcp add weppy-roblox-mcp -- npx -y "@weppy/roblox-mcp"
|
|
414
|
+
if ($LASTEXITCODE -ne 0) {
|
|
415
|
+
throw 'codex mcp add failed'
|
|
416
|
+
}
|
|
417
|
+
Write-Ok "Registered: $appName"
|
|
418
|
+
}
|
|
419
|
+
else {
|
|
420
|
+
Write-Fail "Failed: $appName (CLI/config unavailable)"
|
|
421
|
+
}
|
|
283
422
|
}
|
|
284
423
|
"gemini-cli" {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
424
|
+
if ($geminiConfigured) {
|
|
425
|
+
Write-Ok "Already configured: $appName"
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
Add-McpToConfig $geminiConfig
|
|
429
|
+
Write-Ok "Registered: $appName"
|
|
430
|
+
}
|
|
289
431
|
}
|
|
290
432
|
}
|
|
291
433
|
}
|
package/install.sh
CHANGED
|
@@ -100,6 +100,48 @@ fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
|
100
100
|
'
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
is_json_mcp_configured() {
|
|
104
|
+
local config_path="$1"
|
|
105
|
+
|
|
106
|
+
[ -f "$config_path" ] || return 1
|
|
107
|
+
|
|
108
|
+
MCP_CONFIG_PATH="$config_path" node -e '
|
|
109
|
+
const fs = require("fs");
|
|
110
|
+
const configPath = process.env.MCP_CONFIG_PATH;
|
|
111
|
+
try {
|
|
112
|
+
const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
113
|
+
process.exit(config?.mcpServers?.["weppy-roblox-mcp"] ? 0 : 1);
|
|
114
|
+
} catch {
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
' >/dev/null 2>&1
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
is_codex_config_configured() {
|
|
121
|
+
local config_path="$1"
|
|
122
|
+
|
|
123
|
+
[ -f "$config_path" ] || return 1
|
|
124
|
+
grep -Eq '^[[:space:]]*\[mcp_servers\.weppy-roblox-mcp\][[:space:]]*$' "$config_path"
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
resolve_optional_cli_command() {
|
|
128
|
+
local command_name="$1"
|
|
129
|
+
local npm_prefix=""
|
|
130
|
+
|
|
131
|
+
if command -v "$command_name" >/dev/null 2>&1; then
|
|
132
|
+
command -v "$command_name"
|
|
133
|
+
return 0
|
|
134
|
+
fi
|
|
135
|
+
|
|
136
|
+
npm_prefix=$(npm prefix -g 2>/dev/null || true)
|
|
137
|
+
if [ -n "$npm_prefix" ] && [ -x "$npm_prefix/bin/$command_name" ]; then
|
|
138
|
+
printf "%s\n" "$npm_prefix/bin/$command_name"
|
|
139
|
+
return 0
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
return 1
|
|
143
|
+
}
|
|
144
|
+
|
|
103
145
|
is_lfs_pointer() {
|
|
104
146
|
local file_path="$1"
|
|
105
147
|
|
|
@@ -204,10 +246,19 @@ declare -a DETECTED_NAMES=()
|
|
|
204
246
|
declare -a DETECTED_TYPES=()
|
|
205
247
|
declare -a NOT_DETECTED=()
|
|
206
248
|
|
|
207
|
-
# Claude Code
|
|
208
|
-
|
|
249
|
+
# Claude Code
|
|
250
|
+
CLAUDE_PROJECT_MCP_CONFIG="$PWD/.mcp.json"
|
|
251
|
+
CLAUDE_GLOBAL_MCP_CONFIG="$HOME/.claude/mcp.json"
|
|
252
|
+
CLAUDE_CLI_COMMAND="$(resolve_optional_cli_command claude 2>/dev/null || true)"
|
|
253
|
+
|
|
254
|
+
if is_json_mcp_configured "$CLAUDE_PROJECT_MCP_CONFIG" || is_json_mcp_configured "$CLAUDE_GLOBAL_MCP_CONFIG"; then
|
|
255
|
+
DETECTED_NAMES+=("Claude Code (configured)")
|
|
256
|
+
DETECTED_TYPES+=("claude-code")
|
|
257
|
+
elif [ -n "$CLAUDE_CLI_COMMAND" ]; then
|
|
209
258
|
DETECTED_NAMES+=("Claude Code (CLI)")
|
|
210
259
|
DETECTED_TYPES+=("claude-code")
|
|
260
|
+
else
|
|
261
|
+
NOT_DETECTED+=("Claude Code (not found)")
|
|
211
262
|
fi
|
|
212
263
|
|
|
213
264
|
# Claude Desktop (macOS)
|
|
@@ -229,7 +280,12 @@ else
|
|
|
229
280
|
fi
|
|
230
281
|
|
|
231
282
|
# Codex CLI
|
|
232
|
-
|
|
283
|
+
CODEX_CONFIG="$HOME/.codex/config.toml"
|
|
284
|
+
CODEX_CLI_COMMAND="$(resolve_optional_cli_command codex 2>/dev/null || true)"
|
|
285
|
+
if is_codex_config_configured "$CODEX_CONFIG"; then
|
|
286
|
+
DETECTED_NAMES+=("Codex CLI (configured)")
|
|
287
|
+
DETECTED_TYPES+=("codex-cli")
|
|
288
|
+
elif [ -n "$CODEX_CLI_COMMAND" ]; then
|
|
233
289
|
DETECTED_NAMES+=("Codex CLI")
|
|
234
290
|
DETECTED_TYPES+=("codex-cli")
|
|
235
291
|
else
|
|
@@ -237,7 +293,13 @@ else
|
|
|
237
293
|
fi
|
|
238
294
|
|
|
239
295
|
# Gemini CLI
|
|
240
|
-
|
|
296
|
+
# Gemini CLI
|
|
297
|
+
GEMINI_CONFIG="$HOME/.gemini/settings.json"
|
|
298
|
+
GEMINI_CLI_COMMAND="$(resolve_optional_cli_command gemini 2>/dev/null || true)"
|
|
299
|
+
if is_json_mcp_configured "$GEMINI_CONFIG"; then
|
|
300
|
+
DETECTED_NAMES+=("Gemini CLI (configured)")
|
|
301
|
+
DETECTED_TYPES+=("gemini-cli")
|
|
302
|
+
elif [ -n "$GEMINI_CLI_COMMAND" ]; then
|
|
241
303
|
DETECTED_NAMES+=("Gemini CLI")
|
|
242
304
|
DETECTED_TYPES+=("gemini-cli")
|
|
243
305
|
else
|
|
@@ -302,7 +364,9 @@ else
|
|
|
302
364
|
|
|
303
365
|
case "$app_type" in
|
|
304
366
|
claude-code)
|
|
305
|
-
if
|
|
367
|
+
if is_json_mcp_configured "$CLAUDE_PROJECT_MCP_CONFIG" || is_json_mcp_configured "$CLAUDE_GLOBAL_MCP_CONFIG"; then
|
|
368
|
+
success "Already configured: $app_name"
|
|
369
|
+
elif [ -n "$CLAUDE_CLI_COMMAND" ] && "$CLAUDE_CLI_COMMAND" mcp add weppy-roblox-mcp -- npx -y @weppy/roblox-mcp 2>/dev/null; then
|
|
306
370
|
success "Registered: $app_name"
|
|
307
371
|
else
|
|
308
372
|
fail "Failed: $app_name"
|
|
@@ -323,16 +387,25 @@ else
|
|
|
323
387
|
fi
|
|
324
388
|
;;
|
|
325
389
|
codex-cli)
|
|
326
|
-
|
|
327
|
-
|
|
390
|
+
if is_codex_config_configured "$CODEX_CONFIG"; then
|
|
391
|
+
success "Already configured: $app_name"
|
|
392
|
+
else
|
|
393
|
+
[ -n "$CODEX_CLI_COMMAND" ] && "$CODEX_CLI_COMMAND" mcp remove weppy-roblox-mcp >/dev/null 2>&1 || true
|
|
394
|
+
fi
|
|
395
|
+
if is_codex_config_configured "$CODEX_CONFIG"; then
|
|
396
|
+
:
|
|
397
|
+
elif [ -n "$CODEX_CLI_COMMAND" ] && "$CODEX_CLI_COMMAND" mcp add weppy-roblox-mcp -- npx -y @weppy/roblox-mcp 2>/dev/null; then
|
|
328
398
|
success "Registered: $app_name"
|
|
399
|
+
elif is_codex_config_configured "$CODEX_CONFIG"; then
|
|
400
|
+
success "Already configured: $app_name"
|
|
329
401
|
else
|
|
330
402
|
fail "Failed: $app_name"
|
|
331
403
|
fi
|
|
332
404
|
;;
|
|
333
405
|
gemini-cli)
|
|
334
|
-
|
|
335
|
-
|
|
406
|
+
if is_json_mcp_configured "$GEMINI_CONFIG"; then
|
|
407
|
+
success "Already configured: $app_name"
|
|
408
|
+
elif add_mcp_to_config "$GEMINI_CONFIG"; then
|
|
336
409
|
success "Registered: $app_name"
|
|
337
410
|
else
|
|
338
411
|
fail "Failed: $app_name"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weppy/roblox-mcp",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"description": "MCP (Model Context Protocol) server for Roblox Studio integration - enables AI coding agents to interact with Roblox Studio in real-time",
|
|
5
5
|
"main": "plugins/weppy-roblox-mcp/dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r,a as R,u as M,b as B,c as D,j as e,T as m}from"./index-E1cuNPsJ.js";import{I as V}from"./InfoLabel-CBAqTqRy.js";import{D as F,P as G}from"./PropertyDiff-D34Apw3G.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};
|
|
1
|
+
import{r,a as R,u as M,b as B,c as D,j as e,T as m}from"./index-BNdn6WpU.js";import{I as V}from"./InfoLabel-B_Ys60mi.js";import{D as F,P as G}from"./PropertyDiff-BbsF9z4D.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
|
+
import{r as i,a as D,D as O,u as F,j as e,T as I,c as V,i as U}from"./index-BNdn6WpU.js";import{C as G}from"./ConfirmModal-CInBBLZW.js";import{u as H,T as Z,D as W,a as q}from"./TierComparison-D4uVUGcZ.js";import{t as d}from"./TierPromo.module-CAoUYgIx.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),[g,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 D.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,g)},[x,l,g]),_=i.useCallback(async()=>{await D.post("/api/dashboard/changelog/clear"),p([]),a(0),f(!1)},[]);return i.useEffect(()=>{x(l,g)},[x,l,g]),i.useEffect(()=>{const h=new O;b.current=h,h.connect();const o=h.on("command",()=>{x(l,g)});return()=>{o(),h.disconnect(),b.current=null}},[x,l,g]),{entries:t,total:s,hasMore:u,loading:r,offset:l,statusFilter:g,setOffset:C,setStatusFilter:j,refresh:y,clear:_}}const K="_card_1n89u_2",Q="_header_1n89u_17",X="_statusBadge_1n89u_24",Y="_statusDot_1n89u_35",ee="_active_1n89u_41",se="_completed_1n89u_50",te="_timeRange_1n89u_58",ae="_summaryList_1n89u_65",ne="_summaryItem_1n89u_71",oe="_summaryIcon_1n89u_80",ce="_summaryText_1n89u_86",ie="_progressBar_1n89u_91",re="_progressFill_1n89u_99",le="_emptySummary_1n89u_112",de="_contextBlock_1n89u_120",ge="_contextLabel_1n89u_129",me="_contextValue_1n89u_137",n={card:K,header:Q,statusBadge:X,statusDot:Y,active:ee,completed:se,timeRange:te,summaryList:ae,summaryItem:ne,summaryIcon:oe,summaryText:ce,progressBar:ie,progressFill:re,emptySummary:le,contextBlock:de,contextLabel:ge,contextValue:me};function E(t){if(!t)return"--:--";const p=new Date(t);return`${String(p.getHours()).padStart(2,"0")}:${String(p.getMinutes()).padStart(2,"0")}`}function he({entry:t,onClick:p}){var S,N,k,B,L,w,A,M,R,P;const{t:s}=F(),a=t.changeSummary,u=t.status==="active",f=t.isBootstrapOnly===!0,r=[],v=a.scriptsModified+a.scriptsCreated;if(v>0){const m=[];a.scriptsModified>0&&m.push(`${a.scriptsModified} ${s("changelog.card.modified","modified")}`),a.scriptsCreated>0&&m.push(`${a.scriptsCreated} ${s("changelog.card.created","created")}`);const T=`${v} ${s("changelog.card.scripts","scripts")} ${m.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 m=[];a.instancesCreated>0&&m.push(`${a.instancesCreated} ${s("changelog.card.created","created")}`),a.instancesDeleted>0&&m.push(`${a.instancesDeleted} ${s("changelog.card.deleted","deleted")}`),a.instancesMoved>0&&m.push(`${a.instancesMoved} ${s("changelog.card.moved","moved")}`);const T=`${l} ${s("changelog.card.instances","instances")} ${m.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=E(t.startTime),g=u?s("changelog.card.inProgress","in progress"):t.endTime?E(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=(P=(R=t.verificationSummary)==null?void 0:R.label)==null?void 0:P.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,"~",g]})]}),e.jsx("div",{className:n.summaryList,children:r.length>0?r.map((m,T)=>e.jsxs("div",{className:n.summaryItem,children:[e.jsx("span",{className:n.summaryIcon,children:m.icon}),e.jsx(I,{text:m.tooltip,children:e.jsx("span",{className:n.summaryText,children:m.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 pe="_page_1srvj_2",ue="_limitNotice_1srvj_9",fe="_limitNoticeTitle_1srvj_18",xe="_limitNoticeText_1srvj_25",_e="_headerRow_1srvj_31",ve="_header_1srvj_31",je="_clearButton_1srvj_48",be="_headerSub_1srvj_57",ye="_filterTabs_1srvj_67",Ne="_filterTab_1srvj_67",Ce="_filterTabActive_1srvj_90",Se="_list_1srvj_96",Te="_empty_1srvj_103",$e="_loading_1srvj_112",Ie="_pagination_1srvj_121",ke="_pageInfo_1srvj_129",Be="_btn_1srvj_135",c={page:pe,limitNotice:ue,limitNoticeTitle:fe,limitNoticeText:xe,headerRow:_e,header:ve,clearButton:je,headerSub:be,filterTabs:ye,filterTab:Ne,filterTabActive:Ce,list:Se,empty:Te,loading:$e,pagination:Ie,pageInfo:ke,btn:Be},$=10,Le=[{key:"all",label:"changelog.filter.all"},{key:"active",label:"changelog.filter.active"},{key:"completed",label:"changelog.filter.completed"}];function Pe(){const{t}=F(),p=V(),s=J(),a=H(),{show:u}=U(),[f,r]=i.useState(!1),[v,l]=i.useState(!1),[C,g]=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:Le.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(he,{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:d.progressPromoWrap,children:[e.jsxs("div",{className:d.progressPromo,children:[e.jsxs("div",{className:d.progressMain,children:[e.jsxs("div",{className:d.progressLabel,children:[e.jsx("span",{children:t("changelog.basic.metricLabel","Visible Changelog / Total")}),e.jsxs("span",{children:[y," / ",_]})]}),e.jsx("div",{className:d.progressBar,children:e.jsx("div",{className:d.progressFill,style:{width:`${_>0?Math.min(y/_*100,100):0}%`}})}),e.jsxs("div",{className:d.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:d.progressText,children:t("tier.banner.save","Save AI tokens with Pro!")}),e.jsxs("div",{className:d.actions,children:[e.jsx("button",{className:`${d.btn} ${d.btnOutline}`,onClick:()=>g(!0),children:t("tier.compare","Basic vs Pro")}),e.jsx("a",{className:`${d.btn} ${d.btnPrimary}`,href:Z.changelog,target:"_blank",rel:"noreferrer",children:t("tier.upgrade","Upgrade to Pro")})]})]}),e.jsx(W,{variant:"centered"})]})]}),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:()=>g(!1)})]})}export{Pe as Component};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as s,s as e}from"./index-
|
|
1
|
+
import{j as s,s as e}from"./index-BNdn6WpU.js";function x({open:c,title:i,message:n,cancelLabel:t,confirmLabel:o,loading:a=!1,onCancel:l,onConfirm:r}){return c?s.jsx("div",{className:e.backdrop,onClick:a?void 0:l,children:s.jsxs("div",{className:e.modal,onClick:d=>d.stopPropagation(),children:[s.jsx("h2",{className:e.title,children:i}),s.jsx("p",{className:e.message,children:n}),s.jsxs("div",{className:e.actions,children:[s.jsx("button",{className:e.cancelButton,onClick:l,disabled:a,children:t}),s.jsx("button",{className:e.confirmButton,onClick:r,disabled:a,children:a?"...":o})]})]})}):null}export{x as C};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as $,r,j as e,d as R,a as N,D as I,i as L,T as M}from"./index-
|
|
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-BNdn6WpU.js";import{I as a}from"./InfoLabel-B_Ys60mi.js";import{S as A}from"./StatusBadge-FYpJOX7r.js";import{C as E}from"./ConfirmModal-CInBBLZW.js";import{u as P,f as k}from"./useLiveUptime-D5Ux8dA5.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}=$(),c=r.useRef(null);return r.useEffect(()=>{const l=c.current;l&&(l.scrollTop=l.scrollHeight)},[n.length]),e.jsx("div",{ref:c,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:c}=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!=="disconnected"&&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:c,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",ce="_btn_12byi_143",oe="_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:ce,emptyRow:oe};function w(n,t){const c=Math.max(0,Math.floor((Date.now()-n)/1e3));return c<60?`${c}${t("connection.time.secondsAgo","s ago")}`:c<3600?`${Math.floor(c/60)}${t("connection.time.minutesAgo","m ago")}`:`${Math.floor(c/3600)}${t("connection.time.hoursAgo","h ago")}`}function pe(){var b;const{t:n}=$(),{status:t,connectionInfo:c,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==="disconnected",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)})]}),(c==null?void 0:c.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:c.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")," ","(",(c==null?void 0:c.mcpInstanceCount)??0,")"]}),e.jsx("button",{className:s.toggleBtn,onClick:()=>_(o=>!o),"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:c!=null&&c.mcpInstances&&c.mcpInstances.length>0?c.mcpInstances.map(o=>e.jsxs("tr",{children:[e.jsx("td",{children:o.aiClientName??n("connection.agents.unknown","Unknown")}),e.jsx("td",{children:o.pid}),e.jsx("td",{children:o.projectRoot??o.cwd??n("connection.agents.projectRoot.unresolved","Unresolved")}),e.jsx("td",{children:w(o.connectedAt,n)})]},o.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(o=>e.jsxs("tr",{children:[e.jsx("td",{children:o.placeName??o.projectName??"-"}),e.jsx("td",{children:o.clientId.slice(0,10)}),e.jsx("td",{children:w(o.lastSeen,n)}),e.jsx("td",{children:o.pluginVersion??"-"})]},o.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,m as e}from"./index-
|
|
1
|
+
import{j as r,m as e}from"./index-BNdn6WpU.js";function s({label:t,tooltip:o}){return r.jsx(e,{text:o,children:t})}export{s as I};
|