@weppy/roblox-mcp 2.3.1 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +18 -0
- package/README.md +4 -4
- package/docs/en/installation/README.md +2 -2
- package/docs/en/sync/overview.md +1 -1
- package/docs/es/README.md +4 -4
- package/docs/es/installation/README.md +2 -2
- package/docs/es/sync/overview.md +1 -1
- package/docs/id/README.md +4 -4
- package/docs/id/installation/README.md +2 -2
- package/docs/id/sync/overview.md +1 -1
- package/docs/ja/README.md +4 -4
- package/docs/ja/installation/README.md +2 -2
- package/docs/ja/sync/overview.md +1 -1
- package/docs/ko/README.md +4 -4
- package/docs/ko/installation/README.md +2 -2
- package/docs/ko/sync/overview.md +1 -1
- package/docs/pt-br/README.md +4 -4
- package/docs/pt-br/installation/README.md +2 -2
- package/docs/pt-br/sync/overview.md +1 -1
- package/docs/troubleshooting.md +1 -1
- package/llms.txt +1 -1
- 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-ITTDURna.js → ChangelogDetailPage-CDMDeGei.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ChangelogPage-DjVot-60.js → ChangelogPage-Uhx5ND-w.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ConfirmModal-B1q8BGeA.js → ConfirmModal-BHlbjwL7.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ConnectionPage-D4y36l03.js → ConnectionPage-VXh4Hc9N.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{InfoLabel-COMRAIq0.js → InfoLabel-CGOLGj5z.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{OverviewPage-DojgIxVT.js → OverviewPage-CWnqw6VH.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{PlaytestPage-CkEvf6XW.js → PlaytestPage-62dIQkgo.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{PropertyDiff-r9iLxfi8.js → PropertyDiff-DnLJY3ZB.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{SettingsPage-CEs6Ob3d.js → SettingsPage-Bjr3d4mM.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{StatusBadge-DHhSWmAT.js → StatusBadge-6VL6HJhv.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{SyncPage-ifjnfsNg.js → SyncPage-jdplS80I.js} +4 -4
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierComparison-7eRDwSAZ.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromoProgress-DFG_858F.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ToolsPage-B8iwhAW0.css +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ToolsPage-Cc6Vl-VU.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/WhatsNewPage-Lxgj0StO.css +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/WhatsNewPage-WPfXt13q.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/index-BhDELp5r.js +143 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/index-YfUJSF5s.css +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{useLiveUptime-Dco8Aiiz.js → useLiveUptime-BT-AiWEA.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/index.html +2 -2
- package/plugins/weppy-roblox-mcp/dist/index.js +80 -73
- package/plugins/weppy-roblox-mcp/roblox-plugin/WeppyRobloxMCP.rbxm +0 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierComparison-C29caZ6C.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromoProgress-BdEtTxkK.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ToolsPage-BOIC0ngW.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ToolsPage-BZZZ3FXe.css +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/index-CQYn3Wfp.js +0 -129
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/index-DYnjsp-e.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.
|
|
9
|
+
"version": "2.4.0"
|
|
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.
|
|
16
|
+
"version": "2.4.0",
|
|
17
17
|
"author": {
|
|
18
18
|
"name": "hope1026"
|
|
19
19
|
},
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,24 @@ All notable changes to this project will be documented in this file.
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
|
|
11
|
+
## [2.4.0] - 2026-04-10
|
|
12
|
+
|
|
13
|
+
### ⚠️ BREAKING CHANGES
|
|
14
|
+
|
|
15
|
+
- **Tool statistics and changelog history format updated** — The internal storage format for tool execution statistics (`tool-stats.json`) and changelog history has changed. Existing data will be automatically reset on first launch after upgrading. You will start with fresh statistics — previous history is not migrated.
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
- **Dashboard "What's New" page** — A new announcements page in the dashboard keeps you informed about important changes, breaking updates, and tips. Accessible via the bell icon in the sidebar, with unread indicators for new announcements.
|
|
20
|
+
- **Improved blocked-tool feedback** — When a Pro-only tool is used on Basic tier, the dashboard and plugin now show clearer outcome details (fallback, unsupported, failed) instead of generic error labels.
|
|
21
|
+
- **Connection stability improvements** — Added handshake timeout, connection cancel button, and license reconnect race condition fixes for more reliable Studio connections.
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
- **Fix `ws` module not found on install** — Replaced dynamic `require("ws")` with a static import, resolving installation failures where the `ws` dependency could not be located by the bundler.
|
|
26
|
+
|
|
27
|
+
|
|
10
28
|
## [2.3.1] - 2026-04-07
|
|
11
29
|
|
|
12
30
|
### Features
|
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ No copy-pasting code. AI does the work, you review the results.
|
|
|
20
20
|
|
|
21
21
|
Install with the guided web page.
|
|
22
22
|
|
|
23
|
-
👉 **[Install Page](https://
|
|
23
|
+
👉 **[Install Page](https://weppyai.com/en/install)**
|
|
24
24
|
|
|
25
25
|
### Terminal One-Line Install
|
|
26
26
|
|
|
@@ -47,7 +47,7 @@ Automatic MCP registration supports **Claude Code, Claude Desktop, Cursor, Codex
|
|
|
47
47
|
If the one-line install does not work, or automatic installation is not available in your environment:
|
|
48
48
|
|
|
49
49
|
**Step 1** — Install the Roblox Studio plugin:
|
|
50
|
-
[Plugin Installation Guide](
|
|
50
|
+
[Plugin Installation Guide](docs/en/installation/roblox-plugin.md)
|
|
51
51
|
|
|
52
52
|
**Step 2** — Register the MCP server with your AI app:
|
|
53
53
|
|
|
@@ -177,7 +177,7 @@ Yes. See [Cursor Setup](docs/en/installation/ai-apps/cursor.md). Any MCP-compati
|
|
|
177
177
|
Yes. AI can create instances, write scripts, generate terrain, set up lighting, insert assets, configure physics, and more — all inside a live Roblox Studio session. It goes beyond code generation to executable actions.
|
|
178
178
|
|
|
179
179
|
### What is the difference between Basic and Pro?
|
|
180
|
-
Basic (Free) includes MCP tool execution and one-way sync (Studio -> Local). Pro adds bidirectional sync, bulk operations, terrain generation, spatial analysis, audio/animation control, and multi-place support. See the [Pro Upgrade Guide](https://
|
|
180
|
+
Basic (Free) includes MCP tool execution and one-way sync (Studio -> Local). Pro adds bidirectional sync, bulk operations, terrain generation, spatial analysis, audio/animation control, and multi-place support. See the [Pro Upgrade Guide](https://weppyai.com/en/plans).
|
|
181
181
|
|
|
182
182
|
### How is Weppy different from other Roblox MCP servers?
|
|
183
183
|
Weppy uses action-based dispatching instead of separate tools for each function. This reduces AI token consumption significantly. It also provides bidirectional project sync and multi-place support, which most alternatives lack.
|
|
@@ -189,7 +189,7 @@ The server runs on localhost only (127.0.0.1:3002). Forbidden paths (CoreGui, Co
|
|
|
189
189
|
|
|
190
190
|
Bidirectional Sync, advanced build capabilities, and AI token efficiency — all in one upgrade.
|
|
191
191
|
|
|
192
|
-
[Pro Upgrade Guide](https://
|
|
192
|
+
[Pro Upgrade Guide](https://weppyai.com/en/plans)
|
|
193
193
|
|
|
194
194
|
## License
|
|
195
195
|
|
|
@@ -48,7 +48,7 @@ If the one-line install does not work, or automatic installation is not availabl
|
|
|
48
48
|
|
|
49
49
|
Download the plugin file from GitHub, then place it in Roblox Studio's Plugins folder.
|
|
50
50
|
|
|
51
|
-
👉 [Plugin Installation Guide](https://
|
|
51
|
+
👉 [Plugin Installation Guide](https://weppyai.com/en/install#plugin)
|
|
52
52
|
|
|
53
53
|
---
|
|
54
54
|
|
|
@@ -75,7 +75,7 @@ Register the MCP server with your AI app. You can use it with any AI app that su
|
|
|
75
75
|
Browse synced instance trees inside VSCode with Roblox class icons.
|
|
76
76
|
This optional extension requires the Roblox MCP setup above, because it reads sync data from `wrox-project-sync` under your project root.
|
|
77
77
|
|
|
78
|
-
👉 [WROX Roblox Explorer Installation Guide](https://
|
|
78
|
+
👉 [WROX Roblox Explorer Installation Guide](https://weppyai.com/en/install#explorer)
|
|
79
79
|
|
|
80
80
|
Direct listings:
|
|
81
81
|
- [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=weppy.weppy-roblox-explorer)
|
package/docs/en/sync/overview.md
CHANGED
|
@@ -150,4 +150,4 @@ Names containing `~` are escaped to `~~` (e.g. `Part~2` becomes `Part~~2/`). The
|
|
|
150
150
|
|
|
151
151
|
- [Use `luau-lsp` with WROX Sync](./luau-lsp.md)
|
|
152
152
|
- [Tools Overview](../tools/overview.md)
|
|
153
|
-
- [Pro Upgrade Guide](https://
|
|
153
|
+
- [Pro Upgrade Guide](https://weppyai.com/en/plans)
|
package/docs/es/README.md
CHANGED
|
@@ -20,7 +20,7 @@ No necesitas copiar ni pegar código. La IA trabaja y tú verificas los resultad
|
|
|
20
20
|
|
|
21
21
|
Instala siguiendo la guia en la pagina web.
|
|
22
22
|
|
|
23
|
-
👉 **[Pagina de instalacion](https://
|
|
23
|
+
👉 **[Pagina de instalacion](https://weppyai.com/en/install)**
|
|
24
24
|
|
|
25
25
|
### Instalacion por terminal
|
|
26
26
|
|
|
@@ -49,7 +49,7 @@ Si la ejecución de PowerShell está bloqueada en Windows, continúa con la inst
|
|
|
49
49
|
Si la instalacion en un solo comando no funciona, o si no puedes usar la instalacion automatica en tu entorno, usa la instalacion manual de abajo como alternativa.
|
|
50
50
|
|
|
51
51
|
**Paso 1** — Instala el plugin de Roblox Studio:
|
|
52
|
-
[Guia de instalacion del plugin](
|
|
52
|
+
[Guia de instalacion del plugin](installation/roblox-plugin.md)
|
|
53
53
|
|
|
54
54
|
**Paso 2** — Registra el servidor MCP en tu app de IA:
|
|
55
55
|
|
|
@@ -177,7 +177,7 @@ Sí. Consulta [Configuración de Cursor](installation/ai-apps/cursor.md). Cualqu
|
|
|
177
177
|
Sí. La IA puede crear instancias, escribir scripts, generar terrain, configurar iluminación, insertar assets, configurar física y más — todo dentro de una sesión de Studio en vivo. Va más allá de la generación de código hacia acciones ejecutables.
|
|
178
178
|
|
|
179
179
|
### ¿Cuál es la diferencia entre Basic y Pro?
|
|
180
|
-
Basic (gratuito) incluye ejecución de herramientas MCP y sincronización unidireccional (Studio -> Local). Pro agrega sincronización bidireccional, operaciones masivas, generación de terrain, análisis espacial, control de audio/animación y soporte multi-place. Consulta la [Guía de actualización Pro](https://
|
|
180
|
+
Basic (gratuito) incluye ejecución de herramientas MCP y sincronización unidireccional (Studio -> Local). Pro agrega sincronización bidireccional, operaciones masivas, generación de terrain, análisis espacial, control de audio/animación y soporte multi-place. Consulta la [Guía de actualización Pro](https://weppyai.com/en/plans).
|
|
181
181
|
|
|
182
182
|
### ¿Cómo se diferencia Weppy de otros servidores MCP para Roblox?
|
|
183
183
|
Weppy usa despacho basado en acciones en lugar de herramientas separadas para cada función. Esto reduce significativamente el consumo de tokens de IA. También proporciona sincronización bidireccional de proyecto y soporte multi-place, que la mayoría de las alternativas no tienen.
|
|
@@ -189,7 +189,7 @@ El servidor se ejecuta solo en localhost (127.0.0.1:3002). Las rutas prohibidas
|
|
|
189
189
|
|
|
190
190
|
Sync bidireccional, capacidades de creacion avanzadas y eficiencia de tokens de IA — todo en una sola actualizacion.
|
|
191
191
|
|
|
192
|
-
[Guia de actualizacion Pro](https://
|
|
192
|
+
[Guia de actualizacion Pro](https://weppyai.com/en/plans)
|
|
193
193
|
|
|
194
194
|
## Licencia
|
|
195
195
|
|
|
@@ -42,7 +42,7 @@ Si la instalacion en un solo comando no funciona, o cuando no puedes usar la ins
|
|
|
42
42
|
|
|
43
43
|
El plugin conecta Roblox Studio con la IA.
|
|
44
44
|
|
|
45
|
-
👉 [Guía de instalación del plugin](https://
|
|
45
|
+
👉 [Guía de instalación del plugin](https://weppyai.com/en/install#plugin)
|
|
46
46
|
|
|
47
47
|
### Paso 2: Registrar el Servidor MCP en tu App de IA
|
|
48
48
|
|
|
@@ -68,7 +68,7 @@ Configura el servidor MCP en tu app de IA para que pueda comunicarse con Roblox
|
|
|
68
68
|
Explora los árboles de instancias sincronizados dentro de VSCode con iconos de clases Roblox.
|
|
69
69
|
Esta extension opcional requiere completar antes la instalacion de Roblox MCP, porque Explorer lee los datos de Sync desde `wrox-project-sync` dentro de la raiz del proyecto.
|
|
70
70
|
|
|
71
|
-
👉 [Guía de instalación de WROX Roblox Explorer](https://
|
|
71
|
+
👉 [Guía de instalación de WROX Roblox Explorer](https://weppyai.com/en/install#explorer)
|
|
72
72
|
|
|
73
73
|
Instalación directa:
|
|
74
74
|
- [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=weppy.weppy-roblox-explorer)
|
package/docs/es/sync/overview.md
CHANGED
|
@@ -150,4 +150,4 @@ Los nombres que contienen `~` se escapan como `~~` (ej. `Part~2` → `Part~~2/`)
|
|
|
150
150
|
|
|
151
151
|
- [Usar `luau-lsp` con WROX Sync](./luau-lsp.md)
|
|
152
152
|
- [Cobertura de herramientas (Tools Overview)](../tools/overview.md)
|
|
153
|
-
- [Guia de upgrade Pro](https://
|
|
153
|
+
- [Guia de upgrade Pro](https://weppyai.com/en/plans)
|
package/docs/id/README.md
CHANGED
|
@@ -20,7 +20,7 @@ Tidak perlu copy-paste kode. AI bekerja dan kamu memverifikasi hasilnya.
|
|
|
20
20
|
|
|
21
21
|
Install mengikuti panduan di halaman web.
|
|
22
22
|
|
|
23
|
-
👉 **[Halaman Instalasi](https://
|
|
23
|
+
👉 **[Halaman Instalasi](https://weppyai.com/en/install)**
|
|
24
24
|
|
|
25
25
|
### Instalasi Terminal
|
|
26
26
|
|
|
@@ -49,7 +49,7 @@ Jika eksekusi PowerShell diblokir di Windows, lanjutkan dengan instalasi manual
|
|
|
49
49
|
Jika instalasi satu perintah tidak berjalan, atau instalasi otomatis tidak bisa dipakai di lingkunganmu, gunakan instalasi manual di bawah sebagai alternatif.
|
|
50
50
|
|
|
51
51
|
**Langkah 1** — Install plugin Roblox Studio:
|
|
52
|
-
[Panduan instalasi plugin](
|
|
52
|
+
[Panduan instalasi plugin](installation/roblox-plugin.md)
|
|
53
53
|
|
|
54
54
|
**Langkah 2** — Daftarkan MCP server di aplikasi AI:
|
|
55
55
|
|
|
@@ -177,7 +177,7 @@ Ya. Lihat [Setup Cursor](installation/ai-apps/cursor.md). Semua klien AI yang ko
|
|
|
177
177
|
Ya. AI dapat membuat instance, menulis script, menghasilkan terrain, mengatur lighting, menyisipkan asset, mengkonfigurasi fisika, dan lainnya — semua di dalam sesi Studio yang sedang berjalan. Ini melampaui pembuatan kode menuju aksi yang dapat dieksekusi.
|
|
178
178
|
|
|
179
179
|
### Apa perbedaan antara Basic dan Pro?
|
|
180
|
-
Basic (gratis) mencakup eksekusi alat MCP dan sinkronisasi satu arah (Studio -> Local). Pro menambahkan sinkronisasi dua arah, operasi massal, pembuatan terrain, analisis spasial, kontrol audio/animasi, dan dukungan multi-place. Lihat [Panduan Upgrade Pro](https://
|
|
180
|
+
Basic (gratis) mencakup eksekusi alat MCP dan sinkronisasi satu arah (Studio -> Local). Pro menambahkan sinkronisasi dua arah, operasi massal, pembuatan terrain, analisis spasial, kontrol audio/animasi, dan dukungan multi-place. Lihat [Panduan Upgrade Pro](https://weppyai.com/en/plans).
|
|
181
181
|
|
|
182
182
|
### Apa bedanya Weppy dengan server MCP Roblox lainnya?
|
|
183
183
|
Weppy menggunakan dispatching berbasis aksi alih-alih alat terpisah untuk setiap fungsi. Ini mengurangi konsumsi token AI secara signifikan. Weppy juga menyediakan sinkronisasi proyek dua arah dan dukungan multi-place, yang tidak dimiliki kebanyakan alternatif lain.
|
|
@@ -189,7 +189,7 @@ Server hanya berjalan di localhost (127.0.0.1:3002). Path terlarang (CoreGui, Co
|
|
|
189
189
|
|
|
190
190
|
Sync dua arah, kemampuan kreasi lanjutan, dan efisiensi token AI — semua dalam satu upgrade.
|
|
191
191
|
|
|
192
|
-
[Panduan Upgrade Pro](https://
|
|
192
|
+
[Panduan Upgrade Pro](https://weppyai.com/en/plans)
|
|
193
193
|
|
|
194
194
|
## Lisensi
|
|
195
195
|
|
|
@@ -46,7 +46,7 @@ Jika instalasi satu perintah tidak berjalan, atau jika instalasi otomatis tidak
|
|
|
46
46
|
|
|
47
47
|
Download file plugin dari GitHub, lalu taruh di folder Plugins Roblox Studio.
|
|
48
48
|
|
|
49
|
-
👉 [Panduan Instalasi Plugin](https://
|
|
49
|
+
👉 [Panduan Instalasi Plugin](https://weppyai.com/en/install#plugin)
|
|
50
50
|
|
|
51
51
|
---
|
|
52
52
|
|
|
@@ -73,7 +73,7 @@ Daftarkan MCP server ke aplikasi AI yang kamu pakai. Bisa digunakan di semua apl
|
|
|
73
73
|
Jelajahi tree instance yang sudah disinkronkan di dalam VSCode dengan ikon kelas Roblox.
|
|
74
74
|
Ekstensi opsional ini mengharuskan setup Roblox MCP di atas sudah selesai lebih dulu, karena Explorer membaca data Sync dari `wrox-project-sync` di bawah root proyek.
|
|
75
75
|
|
|
76
|
-
👉 [Panduan Instalasi WROX Roblox Explorer](https://
|
|
76
|
+
👉 [Panduan Instalasi WROX Roblox Explorer](https://weppyai.com/en/install#explorer)
|
|
77
77
|
|
|
78
78
|
Instal langsung:
|
|
79
79
|
- [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=weppy.weppy-roblox-explorer)
|
package/docs/id/sync/overview.md
CHANGED
|
@@ -150,4 +150,4 @@ Nama yang mengandung `~` di-escape menjadi `~~` (contoh: `Part~2` → `Part~~2/`
|
|
|
150
150
|
|
|
151
151
|
- [Menggunakan `luau-lsp` dengan WROX Sync](./luau-lsp.md)
|
|
152
152
|
- [Cakupan tool (Tools Overview)](../tools/overview.md)
|
|
153
|
-
- [Panduan Upgrade Pro](https://
|
|
153
|
+
- [Panduan Upgrade Pro](https://weppyai.com/en/plans)
|
package/docs/ja/README.md
CHANGED
|
@@ -20,7 +20,7 @@ Claude、Codex、GeminiなどのAIコーディングエージェントは強力
|
|
|
20
20
|
|
|
21
21
|
Webページのガイドに沿ってインストールできます。
|
|
22
22
|
|
|
23
|
-
👉 **[インストールページ](https://
|
|
23
|
+
👉 **[インストールページ](https://weppyai.com/ja/install)**
|
|
24
24
|
|
|
25
25
|
### ターミナル ワンラインインストール
|
|
26
26
|
|
|
@@ -47,7 +47,7 @@ AIアプリを再起動し、Roblox Studioを再起動してください。
|
|
|
47
47
|
ワンラインインストールが動作しない場合:
|
|
48
48
|
|
|
49
49
|
**Step 1** — Roblox Studioプラグインのインストール:
|
|
50
|
-
[プラグインインストールガイド](
|
|
50
|
+
[プラグインインストールガイド](installation/roblox-plugin.md)
|
|
51
51
|
|
|
52
52
|
**Step 2** — AIアプリにMCPサーバーを登録:
|
|
53
53
|
|
|
@@ -175,7 +175,7 @@ Roblox Studioプラグインをインストールし、Claude CodeにMCPサー
|
|
|
175
175
|
はい。AIはインスタンスの作成、スクリプトの記述、地形の生成、ライティングの設定、アセットの挿入、物理の設定など、すべてをライブStudioセッション内で直接実行します。コード生成を超えて実行可能なアクションまで処理します。
|
|
176
176
|
|
|
177
177
|
### BasicとProの違いは?
|
|
178
|
-
Basic(無料)にはMCPツール実行と片方向同期(Studio -> Local)が含まれます。Proは双方向同期、バルク操作、地形生成、空間分析、オーディオ/アニメーション制御、マルチPlaceサポートを追加します。[Proアップグレードガイド](https://
|
|
178
|
+
Basic(無料)にはMCPツール実行と片方向同期(Studio -> Local)が含まれます。Proは双方向同期、バルク操作、地形生成、空間分析、オーディオ/アニメーション制御、マルチPlaceサポートを追加します。[Proアップグレードガイド](https://weppyai.com/ja/plans)を参照してください。
|
|
179
179
|
|
|
180
180
|
### Weppyは他のRoblox MCPサーバーとどう違いますか?
|
|
181
181
|
Weppyは機能ごとに個別ツールを分ける代わりにアクションベースのディスパッチを使用します。これによりAIトークン消費が大幅に削減されます。また、双方向プロジェクト同期とマルチPlaceサポートを提供しますが、他の代替製品にはないことがほとんどです。
|
|
@@ -187,7 +187,7 @@ Weppyは機能ごとに個別ツールを分ける代わりにアクションベ
|
|
|
187
187
|
|
|
188
188
|
双方向Sync、高度な制作機能、AIトークン効率 — 一度のアップグレードで全てを手に入れる。
|
|
189
189
|
|
|
190
|
-
[Proアップグレードガイド](https://
|
|
190
|
+
[Proアップグレードガイド](https://weppyai.com/ja/plans)
|
|
191
191
|
|
|
192
192
|
## ライセンス
|
|
193
193
|
|
|
@@ -46,7 +46,7 @@ WindowsでPowerShellの実行がブロックされる場合は、下の手動イ
|
|
|
46
46
|
|
|
47
47
|
GitHubからプラグインファイルをダウンロードして、Roblox StudioのPluginsフォルダに配置します。
|
|
48
48
|
|
|
49
|
-
👉 [プラグインインストールガイド](https://
|
|
49
|
+
👉 [プラグインインストールガイド](https://weppyai.com/ja/install#plugin)
|
|
50
50
|
|
|
51
51
|
---
|
|
52
52
|
|
|
@@ -73,7 +73,7 @@ GitHubからプラグインファイルをダウンロードして、Roblox Stud
|
|
|
73
73
|
同期されたインスタンスツリーをRobloxクラスアイコン付きでVSCode内で閲覧できます。
|
|
74
74
|
この拡張を使うには、先に上記のRoblox MCPセットアップを完了している必要があります。Explorer はプロジェクトルート配下の `wrox-project-sync` にある Sync データを読み取るためです。
|
|
75
75
|
|
|
76
|
-
👉 [WROX Roblox Explorerインストールガイド](https://
|
|
76
|
+
👉 [WROX Roblox Explorerインストールガイド](https://weppyai.com/ja/install#explorer)
|
|
77
77
|
|
|
78
78
|
直接インストール:
|
|
79
79
|
- [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=weppy.weppy-roblox-explorer)
|
package/docs/ja/sync/overview.md
CHANGED
package/docs/ko/README.md
CHANGED
|
@@ -20,7 +20,7 @@ Claude, Codex, Gemini 같은 AI 코딩 에이전트는 강력하지만 — Roblo
|
|
|
20
20
|
|
|
21
21
|
웹페이지에서 안내에 따라 설치할 수 있습니다.
|
|
22
22
|
|
|
23
|
-
👉 **[설치 페이지](https://
|
|
23
|
+
👉 **[설치 페이지](https://weppyai.com/ko/install)**
|
|
24
24
|
|
|
25
25
|
### 터미널 원라인 설치
|
|
26
26
|
|
|
@@ -47,7 +47,7 @@ AI 앱을 다시 열고 Roblox Studio를 재시작하세요.
|
|
|
47
47
|
원라인 설치가 동작하지 않거나 환경상 자동 설치를 사용할 수 없는 경우:
|
|
48
48
|
|
|
49
49
|
**1단계** — Roblox Studio 플러그인 설치:
|
|
50
|
-
[플러그인 설치 가이드](
|
|
50
|
+
[플러그인 설치 가이드](installation/roblox-plugin.md)
|
|
51
51
|
|
|
52
52
|
**2단계** — AI 앱에 MCP 서버 등록:
|
|
53
53
|
|
|
@@ -175,7 +175,7 @@ Roblox Studio 플러그인을 설치한 뒤, Claude Code에 MCP 서버(`npx -y @
|
|
|
175
175
|
네. AI가 인스턴스 생성, 스크립트 작성, 지형 생성, 조명 설정, 에셋 삽입, 물리 설정 등을 라이브 Studio 세션 안에서 직접 수행합니다. 코드 생성을 넘어 실행 가능한 작업까지 처리합니다.
|
|
176
176
|
|
|
177
177
|
### Basic과 Pro의 차이는?
|
|
178
|
-
Basic(무료)은 MCP 도구 실행과 단방향 동기화(Studio -> Local)를 포함합니다. Pro는 양방향 동기화, 대량 작업, 지형 생성, 공간 분석, 오디오/애니메이션 제어, 멀티 Place 지원을 추가합니다. [Pro 업그레이드 가이드](https://
|
|
178
|
+
Basic(무료)은 MCP 도구 실행과 단방향 동기화(Studio -> Local)를 포함합니다. Pro는 양방향 동기화, 대량 작업, 지형 생성, 공간 분석, 오디오/애니메이션 제어, 멀티 Place 지원을 추가합니다. [Pro 업그레이드 가이드](https://weppyai.com/ko/plans)를 참고하세요.
|
|
179
179
|
|
|
180
180
|
### Weppy는 다른 Roblox MCP 서버와 어떻게 다른가요?
|
|
181
181
|
Weppy는 기능별 도구 분리 대신 액션 기반 디스패칭을 사용합니다. 이로 인해 AI 토큰 소비가 크게 줄어듭니다. 또한 양방향 프로젝트 동기화와 멀티 Place 지원을 제공하는데, 대부분의 대안에는 없는 기능입니다.
|
|
@@ -187,7 +187,7 @@ Weppy는 기능별 도구 분리 대신 액션 기반 디스패칭을 사용합
|
|
|
187
187
|
|
|
188
188
|
양방향 Sync, 고급 제작 기능, AI 토큰 효율 — 한 번의 업그레이드로 모두 누리세요.
|
|
189
189
|
|
|
190
|
-
[Pro 업그레이드 가이드](https://
|
|
190
|
+
[Pro 업그레이드 가이드](https://weppyai.com/ko/plans)
|
|
191
191
|
|
|
192
192
|
## 라이선스
|
|
193
193
|
|
|
@@ -48,7 +48,7 @@ Windows에서 PowerShell 실행이 차단되면 아래 수동 설치로 진행
|
|
|
48
48
|
|
|
49
49
|
GitHub에서 플러그인 파일을 다운로드한 뒤, Roblox Studio의 Plugins 폴더에 넣으면 됩니다.
|
|
50
50
|
|
|
51
|
-
👉 [플러그인 설치 가이드](https://
|
|
51
|
+
👉 [플러그인 설치 가이드](https://weppyai.com/ko/install#plugin)
|
|
52
52
|
|
|
53
53
|
---
|
|
54
54
|
|
|
@@ -75,7 +75,7 @@ GitHub에서 플러그인 파일을 다운로드한 뒤, Roblox Studio의 Plugin
|
|
|
75
75
|
동기화된 인스턴스 트리를 Roblox 클래스 아이콘과 함께 VSCode에서 탐색할 수 있습니다.
|
|
76
76
|
이 확장은 위의 Roblox MCP 설치를 먼저 완료해야 사용할 수 있습니다. Explorer가 프로젝트 루트 아래의 `wrox-project-sync` Sync 데이터를 읽기 때문입니다.
|
|
77
77
|
|
|
78
|
-
👉 [WROX Roblox Explorer 설치 가이드](https://
|
|
78
|
+
👉 [WROX Roblox Explorer 설치 가이드](https://weppyai.com/ko/install#explorer)
|
|
79
79
|
|
|
80
80
|
바로 설치:
|
|
81
81
|
- [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=weppy.weppy-roblox-explorer)
|
package/docs/ko/sync/overview.md
CHANGED
package/docs/pt-br/README.md
CHANGED
|
@@ -20,7 +20,7 @@ Sem necessidade de copiar e colar código. A IA trabalha e você confere os resu
|
|
|
20
20
|
|
|
21
21
|
Instale seguindo o guia na pagina web.
|
|
22
22
|
|
|
23
|
-
👉 **[Pagina de instalacao](https://
|
|
23
|
+
👉 **[Pagina de instalacao](https://weppyai.com/en/install)**
|
|
24
24
|
|
|
25
25
|
### Instalacao por terminal
|
|
26
26
|
|
|
@@ -49,7 +49,7 @@ Se a execução do PowerShell estiver bloqueada no Windows, siga a instalação
|
|
|
49
49
|
Se a instalacao em um comando nao funcionar, ou se a instalacao automatica nao puder ser usada no seu ambiente, use a instalacao manual abaixo como alternativa.
|
|
50
50
|
|
|
51
51
|
**Passo 1** — Instale o plugin do Roblox Studio:
|
|
52
|
-
[Guia de instalacao do plugin](
|
|
52
|
+
[Guia de instalacao do plugin](installation/roblox-plugin.md)
|
|
53
53
|
|
|
54
54
|
**Passo 2** — Registre o servidor MCP no seu app de IA:
|
|
55
55
|
|
|
@@ -177,7 +177,7 @@ Sim. Consulte [Configuração do Cursor](installation/ai-apps/cursor.md). Qualqu
|
|
|
177
177
|
Sim. A IA pode criar instâncias, escrever scripts, gerar terrain, configurar iluminação, inserir assets, configurar física e mais — tudo dentro de uma sessão de Studio ao vivo. Vai além da geração de código para ações executáveis.
|
|
178
178
|
|
|
179
179
|
### Qual é a diferença entre Basic e Pro?
|
|
180
|
-
Basic (gratuito) inclui execução de ferramentas MCP e sincronização unidirecional (Studio -> Local). Pro adiciona sincronização bidirecional, operações em massa, geração de terrain, análise espacial, controle de áudio/animação e suporte multi-place. Consulte o [Guia de upgrade Pro](https://
|
|
180
|
+
Basic (gratuito) inclui execução de ferramentas MCP e sincronização unidirecional (Studio -> Local). Pro adiciona sincronização bidirecional, operações em massa, geração de terrain, análise espacial, controle de áudio/animação e suporte multi-place. Consulte o [Guia de upgrade Pro](https://weppyai.com/en/plans).
|
|
181
181
|
|
|
182
182
|
### Como o Weppy se diferencia de outros servidores MCP para Roblox?
|
|
183
183
|
O Weppy usa despacho baseado em ações em vez de ferramentas separadas para cada função. Isso reduz significativamente o consumo de tokens de IA. Também fornece sincronização bidirecional de projeto e suporte multi-place, que a maioria das alternativas não possui.
|
|
@@ -189,7 +189,7 @@ O servidor roda apenas em localhost (127.0.0.1:3002). Caminhos proibidos (CoreGu
|
|
|
189
189
|
|
|
190
190
|
Sync bidirecional, recursos avancados de criacao e eficiencia de tokens de IA — tudo em uma unica atualizacao.
|
|
191
191
|
|
|
192
|
-
[Guia de upgrade Pro](https://
|
|
192
|
+
[Guia de upgrade Pro](https://weppyai.com/en/plans)
|
|
193
193
|
|
|
194
194
|
## Licença
|
|
195
195
|
|
|
@@ -46,7 +46,7 @@ Se a instalacao em um comando nao funcionar, ou quando a instalacao automatica n
|
|
|
46
46
|
|
|
47
47
|
Baixe o arquivo do plugin no GitHub e coloque na pasta Plugins do Roblox Studio.
|
|
48
48
|
|
|
49
|
-
👉 [Guia de instalação do plugin](https://
|
|
49
|
+
👉 [Guia de instalação do plugin](https://weppyai.com/en/install#plugin)
|
|
50
50
|
|
|
51
51
|
---
|
|
52
52
|
|
|
@@ -73,7 +73,7 @@ Registre o servidor MCP no seu app de IA. Funciona com qualquer app que suporte
|
|
|
73
73
|
Navegue pelas árvores de instâncias sincronizadas dentro do VSCode com ícones de classes Roblox.
|
|
74
74
|
Esta extensao opcional exige que a instalacao do Roblox MCP acima ja esteja concluida, porque o Explorer le os dados de Sync em `wrox-project-sync` dentro da raiz do projeto.
|
|
75
75
|
|
|
76
|
-
👉 [Guia de instalação do WROX Roblox Explorer](https://
|
|
76
|
+
👉 [Guia de instalação do WROX Roblox Explorer](https://weppyai.com/en/install#explorer)
|
|
77
77
|
|
|
78
78
|
Instalação direta:
|
|
79
79
|
- [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=weppy.weppy-roblox-explorer)
|
|
@@ -150,4 +150,4 @@ Nomes que contem `~` sao escapados como `~~` (ex: `Part~2` → `Part~~2/`). Regr
|
|
|
150
150
|
|
|
151
151
|
- [Usar `luau-lsp` com WROX Sync](./luau-lsp.md)
|
|
152
152
|
- [Cobertura de ferramentas (Tools Overview)](../tools/overview.md)
|
|
153
|
-
- [Guia de upgrade Pro](https://
|
|
153
|
+
- [Guia de upgrade Pro](https://weppyai.com/en/plans)
|
package/docs/troubleshooting.md
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
## "Pro feature required" error
|
|
20
20
|
|
|
21
21
|
The action you're requesting requires the Pro tier.
|
|
22
|
-
See [Pro Upgrade Guide](https://
|
|
22
|
+
See [Pro Upgrade Guide](https://weppyai.com/en/plans) for details.
|
|
23
23
|
|
|
24
24
|
## Sync not working
|
|
25
25
|
|
package/llms.txt
CHANGED
|
@@ -55,7 +55,7 @@ Manual alternative:
|
|
|
55
55
|
- WROX Dashboard guide: https://github.com/hope1026/weppy-roblox-mcp/blob/main/docs/en/dashboard/overview.md
|
|
56
56
|
- Troubleshooting: https://github.com/hope1026/weppy-roblox-mcp/blob/main/docs/troubleshooting.md
|
|
57
57
|
- Compatibility: https://github.com/hope1026/weppy-roblox-mcp/blob/main/docs/compatibility.md
|
|
58
|
-
- Pro upgrade: https://
|
|
58
|
+
- Pro upgrade: https://weppyai.com/en/plans
|
|
59
59
|
|
|
60
60
|
## Requirements
|
|
61
61
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weppy/roblox-mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
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-CQYn3Wfp.js";import{I as V}from"./InfoLabel-COMRAIq0.js";import{D as F,P as G}from"./PropertyDiff-r9iLxfi8.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-BhDELp5r.js";import{I as V}from"./InfoLabel-CGOLGj5z.js";import{D as F,P as G}from"./PropertyDiff-DnLJY3ZB.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 +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-CQYn3Wfp.js";import{C as G}from"./ConfirmModal-B1q8BGeA.js";import{u as H,T as Z,D as W,a as q}from"./TierComparison-C29caZ6C.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
|
+
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-BhDELp5r.js";import{C as G}from"./ConfirmModal-BHlbjwL7.js";import{u as H,T as Z,D as W,a as q}from"./TierComparison-7eRDwSAZ.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};
|