@weppy/roblox-mcp 2.5.1 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.github/workflows/install-test.yml +55 -4
  3. package/CHANGELOG.md +17 -0
  4. package/README.md +29 -46
  5. package/SUPPORT.md +4 -6
  6. package/install.ps1 +7 -5
  7. package/install.sh +4 -2
  8. package/llms-full.txt +8 -688
  9. package/llms.txt +3 -13
  10. package/package.json +1 -1
  11. package/plugins/weppy-roblox-mcp/.claude-plugin/plugin.json +1 -1
  12. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ChangelogDetailPage-DRfFUIvC.js → ChangelogDetailPage-C-ROvHGr.js} +1 -1
  13. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ChangelogPage-Dgl8dBt6.js → ChangelogPage-CPm4ft8m.js} +1 -1
  14. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ConfirmModal-DfdyAPrJ.js → ConfirmModal-BSTYLn14.js} +1 -1
  15. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ConnectionPage-LSvSX1_u.js → ConnectionPage-BeJEgfmf.js} +1 -1
  16. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{InfoLabel-DrK7vhO-.js → InfoLabel-BRbbxjjt.js} +1 -1
  17. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{OverviewPage-CXsGuoPu.js → OverviewPage-BHd6yL_8.js} +1 -1
  18. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{PlaytestPage-CgkzRAqQ.js → PlaytestPage-BiNJCh4I.js} +1 -1
  19. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{PropertyDiff-Dy3MffNh.js → PropertyDiff-BKVe7m6g.js} +1 -1
  20. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SettingsPage-Cg33y021.js +1 -0
  21. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{StatusBadge-hJyzgRAl.js → StatusBadge-A72TDL-q.js} +1 -1
  22. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{SyncPage-eX2Rh-Ct.js → SyncPage-R4Qs9Xt3.js} +1 -1
  23. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierComparison-CQewH4h_.js +1 -0
  24. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{TierPromoProgress-CLAr1gQq.js → TierPromoProgress-DolZjAqX.js} +1 -1
  25. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ToolsPage-CqzfCxxH.js → ToolsPage-DRX93nSV.js} +1 -1
  26. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/WhatsNewPage-uLdiNHd0.js +1 -0
  27. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{index-BfvSPSNj.js → index-oz4Gtzz9.js} +55 -21
  28. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{useLiveUptime-BeRNzFBh.js → useLiveUptime-CRLLCM8t.js} +1 -1
  29. package/plugins/weppy-roblox-mcp/dashboard/dist/index.html +1 -1
  30. package/plugins/weppy-roblox-mcp/dist/index.js +76 -76
  31. package/plugins/weppy-roblox-mcp/roblox-plugin/WeppyRobloxMCP.rbxm +0 -0
  32. package/docs/compatibility.md +0 -44
  33. package/docs/en/dashboard/changelog.md +0 -114
  34. package/docs/en/dashboard/connection.md +0 -77
  35. package/docs/en/dashboard/overview.md +0 -95
  36. package/docs/en/dashboard/playtest.md +0 -61
  37. package/docs/en/dashboard/settings.md +0 -60
  38. package/docs/en/dashboard/sync.md +0 -68
  39. package/docs/en/dashboard/tools.md +0 -69
  40. package/docs/en/explorer/overview.md +0 -104
  41. package/docs/en/installation/README.md +0 -95
  42. package/docs/en/installation/ai-apps/antigravity.md +0 -89
  43. package/docs/en/installation/ai-apps/claude-app.md +0 -78
  44. package/docs/en/installation/ai-apps/claude-code.md +0 -104
  45. package/docs/en/installation/ai-apps/codex-app.md +0 -56
  46. package/docs/en/installation/ai-apps/codex-cli.md +0 -67
  47. package/docs/en/installation/ai-apps/cursor.md +0 -77
  48. package/docs/en/installation/ai-apps/gemini-cli.md +0 -120
  49. package/docs/en/installation/roblox-explorer.md +0 -68
  50. package/docs/en/installation/roblox-plugin.md +0 -96
  51. package/docs/en/pro-upgrade.md +0 -96
  52. package/docs/en/sync/luau-lsp.md +0 -41
  53. package/docs/en/sync/overview.md +0 -153
  54. package/docs/en/tools/assets-and-effects.md +0 -104
  55. package/docs/en/tools/instances-and-properties.md +0 -104
  56. package/docs/en/tools/overview.md +0 -277
  57. package/docs/en/tools/playtest.md +0 -140
  58. package/docs/en/tools/scripting.md +0 -66
  59. package/docs/en/tools/system-and-debugging.md +0 -93
  60. package/docs/en/tools/world-and-environment.md +0 -102
  61. package/docs/es/README.md +0 -209
  62. package/docs/es/dashboard/changelog.md +0 -114
  63. package/docs/es/dashboard/connection.md +0 -77
  64. package/docs/es/dashboard/overview.md +0 -95
  65. package/docs/es/dashboard/playtest.md +0 -61
  66. package/docs/es/dashboard/settings.md +0 -60
  67. package/docs/es/dashboard/sync.md +0 -68
  68. package/docs/es/dashboard/tools.md +0 -69
  69. package/docs/es/explorer/overview.md +0 -104
  70. package/docs/es/installation/README.md +0 -87
  71. package/docs/es/installation/ai-apps/antigravity.md +0 -89
  72. package/docs/es/installation/ai-apps/claude-app.md +0 -78
  73. package/docs/es/installation/ai-apps/claude-code.md +0 -104
  74. package/docs/es/installation/ai-apps/codex-app.md +0 -56
  75. package/docs/es/installation/ai-apps/codex-cli.md +0 -67
  76. package/docs/es/installation/ai-apps/cursor.md +0 -77
  77. package/docs/es/installation/ai-apps/gemini-cli.md +0 -120
  78. package/docs/es/installation/roblox-explorer.md +0 -58
  79. package/docs/es/installation/roblox-plugin.md +0 -85
  80. package/docs/es/pro-upgrade.md +0 -96
  81. package/docs/es/sync/luau-lsp.md +0 -41
  82. package/docs/es/sync/overview.md +0 -153
  83. package/docs/es/tools/assets-and-effects.md +0 -104
  84. package/docs/es/tools/instances-and-properties.md +0 -104
  85. package/docs/es/tools/overview.md +0 -277
  86. package/docs/es/tools/playtest.md +0 -140
  87. package/docs/es/tools/scripting.md +0 -66
  88. package/docs/es/tools/system-and-debugging.md +0 -93
  89. package/docs/es/tools/world-and-environment.md +0 -102
  90. package/docs/id/README.md +0 -209
  91. package/docs/id/dashboard/changelog.md +0 -114
  92. package/docs/id/dashboard/connection.md +0 -77
  93. package/docs/id/dashboard/overview.md +0 -95
  94. package/docs/id/dashboard/playtest.md +0 -61
  95. package/docs/id/dashboard/settings.md +0 -60
  96. package/docs/id/dashboard/sync.md +0 -68
  97. package/docs/id/dashboard/tools.md +0 -69
  98. package/docs/id/explorer/overview.md +0 -104
  99. package/docs/id/installation/README.md +0 -93
  100. package/docs/id/installation/ai-apps/antigravity.md +0 -89
  101. package/docs/id/installation/ai-apps/claude-app.md +0 -78
  102. package/docs/id/installation/ai-apps/claude-code.md +0 -104
  103. package/docs/id/installation/ai-apps/codex-app.md +0 -56
  104. package/docs/id/installation/ai-apps/codex-cli.md +0 -67
  105. package/docs/id/installation/ai-apps/cursor.md +0 -77
  106. package/docs/id/installation/ai-apps/gemini-cli.md +0 -120
  107. package/docs/id/installation/roblox-explorer.md +0 -58
  108. package/docs/id/installation/roblox-plugin.md +0 -85
  109. package/docs/id/pro-upgrade.md +0 -96
  110. package/docs/id/sync/luau-lsp.md +0 -41
  111. package/docs/id/sync/overview.md +0 -153
  112. package/docs/id/tools/assets-and-effects.md +0 -104
  113. package/docs/id/tools/instances-and-properties.md +0 -104
  114. package/docs/id/tools/overview.md +0 -277
  115. package/docs/id/tools/playtest.md +0 -140
  116. package/docs/id/tools/scripting.md +0 -66
  117. package/docs/id/tools/system-and-debugging.md +0 -93
  118. package/docs/id/tools/world-and-environment.md +0 -102
  119. package/docs/installer/assets/index-Bz0amd7x.js +0 -63
  120. package/docs/installer/assets/index-ei4lRUa6.css +0 -1
  121. package/docs/installer/index.html +0 -14
  122. package/docs/installer/manifest.webmanifest +0 -15
  123. package/docs/installer/sw.js +0 -7
  124. package/docs/installer/weppy-icon.png +0 -0
  125. package/docs/ja/README.md +0 -207
  126. package/docs/ja/dashboard/changelog.md +0 -114
  127. package/docs/ja/dashboard/connection.md +0 -77
  128. package/docs/ja/dashboard/overview.md +0 -95
  129. package/docs/ja/dashboard/playtest.md +0 -61
  130. package/docs/ja/dashboard/settings.md +0 -60
  131. package/docs/ja/dashboard/sync.md +0 -68
  132. package/docs/ja/dashboard/tools.md +0 -69
  133. package/docs/ja/explorer/overview.md +0 -104
  134. package/docs/ja/installation/README.md +0 -93
  135. package/docs/ja/installation/ai-apps/antigravity.md +0 -89
  136. package/docs/ja/installation/ai-apps/claude-app.md +0 -78
  137. package/docs/ja/installation/ai-apps/claude-code.md +0 -104
  138. package/docs/ja/installation/ai-apps/codex-app.md +0 -56
  139. package/docs/ja/installation/ai-apps/codex-cli.md +0 -67
  140. package/docs/ja/installation/ai-apps/cursor.md +0 -77
  141. package/docs/ja/installation/ai-apps/gemini-cli.md +0 -120
  142. package/docs/ja/installation/roblox-explorer.md +0 -58
  143. package/docs/ja/installation/roblox-plugin.md +0 -85
  144. package/docs/ja/pro-upgrade.md +0 -96
  145. package/docs/ja/sync/luau-lsp.md +0 -41
  146. package/docs/ja/sync/overview.md +0 -153
  147. package/docs/ja/tools/assets-and-effects.md +0 -104
  148. package/docs/ja/tools/instances-and-properties.md +0 -104
  149. package/docs/ja/tools/overview.md +0 -277
  150. package/docs/ja/tools/playtest.md +0 -140
  151. package/docs/ja/tools/scripting.md +0 -66
  152. package/docs/ja/tools/system-and-debugging.md +0 -93
  153. package/docs/ja/tools/world-and-environment.md +0 -102
  154. package/docs/ko/README.md +0 -207
  155. package/docs/ko/dashboard/changelog.md +0 -114
  156. package/docs/ko/dashboard/connection.md +0 -77
  157. package/docs/ko/dashboard/overview.md +0 -95
  158. package/docs/ko/dashboard/playtest.md +0 -61
  159. package/docs/ko/dashboard/settings.md +0 -60
  160. package/docs/ko/dashboard/sync.md +0 -68
  161. package/docs/ko/dashboard/tools.md +0 -69
  162. package/docs/ko/explorer/overview.md +0 -104
  163. package/docs/ko/installation/README.md +0 -95
  164. package/docs/ko/installation/ai-apps/antigravity.md +0 -88
  165. package/docs/ko/installation/ai-apps/claude-app.md +0 -78
  166. package/docs/ko/installation/ai-apps/claude-code.md +0 -104
  167. package/docs/ko/installation/ai-apps/codex-app.md +0 -56
  168. package/docs/ko/installation/ai-apps/codex-cli.md +0 -67
  169. package/docs/ko/installation/ai-apps/cursor.md +0 -77
  170. package/docs/ko/installation/ai-apps/gemini-cli.md +0 -120
  171. package/docs/ko/installation/roblox-explorer.md +0 -68
  172. package/docs/ko/installation/roblox-plugin.md +0 -96
  173. package/docs/ko/pro-upgrade.md +0 -96
  174. package/docs/ko/sync/luau-lsp.md +0 -41
  175. package/docs/ko/sync/overview.md +0 -153
  176. package/docs/ko/tools/assets-and-effects.md +0 -104
  177. package/docs/ko/tools/instances-and-properties.md +0 -104
  178. package/docs/ko/tools/overview.md +0 -277
  179. package/docs/ko/tools/playtest.md +0 -134
  180. package/docs/ko/tools/scripting.md +0 -66
  181. package/docs/ko/tools/system-and-debugging.md +0 -93
  182. package/docs/ko/tools/world-and-environment.md +0 -102
  183. package/docs/pt-br/README.md +0 -209
  184. package/docs/pt-br/dashboard/changelog.md +0 -114
  185. package/docs/pt-br/dashboard/connection.md +0 -77
  186. package/docs/pt-br/dashboard/overview.md +0 -95
  187. package/docs/pt-br/dashboard/playtest.md +0 -61
  188. package/docs/pt-br/dashboard/settings.md +0 -60
  189. package/docs/pt-br/dashboard/sync.md +0 -68
  190. package/docs/pt-br/dashboard/tools.md +0 -69
  191. package/docs/pt-br/explorer/overview.md +0 -104
  192. package/docs/pt-br/installation/README.md +0 -93
  193. package/docs/pt-br/installation/ai-apps/antigravity.md +0 -89
  194. package/docs/pt-br/installation/ai-apps/claude-app.md +0 -78
  195. package/docs/pt-br/installation/ai-apps/claude-code.md +0 -104
  196. package/docs/pt-br/installation/ai-apps/codex-app.md +0 -56
  197. package/docs/pt-br/installation/ai-apps/codex-cli.md +0 -67
  198. package/docs/pt-br/installation/ai-apps/cursor.md +0 -77
  199. package/docs/pt-br/installation/ai-apps/gemini-cli.md +0 -120
  200. package/docs/pt-br/installation/roblox-explorer.md +0 -58
  201. package/docs/pt-br/installation/roblox-plugin.md +0 -85
  202. package/docs/pt-br/pro-upgrade.md +0 -96
  203. package/docs/pt-br/sync/luau-lsp.md +0 -41
  204. package/docs/pt-br/sync/overview.md +0 -153
  205. package/docs/pt-br/tools/assets-and-effects.md +0 -104
  206. package/docs/pt-br/tools/instances-and-properties.md +0 -104
  207. package/docs/pt-br/tools/overview.md +0 -277
  208. package/docs/pt-br/tools/playtest.md +0 -140
  209. package/docs/pt-br/tools/scripting.md +0 -66
  210. package/docs/pt-br/tools/system-and-debugging.md +0 -93
  211. package/docs/pt-br/tools/world-and-environment.md +0 -102
  212. package/docs/troubleshooting.md +0 -47
  213. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SettingsPage-D2ZBQ2KF.js +0 -1
  214. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierComparison-BwKqP_4s.js +0 -1
  215. package/plugins/weppy-roblox-mcp/dashboard/dist/assets/WhatsNewPage-23o8LmsR.js +0 -1
@@ -1,140 +0,0 @@
1
- # Playtest e testes automatizados
2
-
3
- > Controle o playtest do Roblox Studio com IA, injete scripts de teste e gere logs e relatorios locais automaticamente.
4
-
5
- ## Tools incluidas
6
-
7
- | Tool | Tier | Descricao |
8
- |------|:----:|-----------|
9
- | `system_info` | Pro | acoes `play`, `stop`, `pause`, `resume`, `play_status`, `run_test` |
10
-
11
- > Para outras acoes de `system_info` como `ping`, `connection` e `usage`, consulte [Sistema e depuracao](system-and-debugging.md).
12
-
13
- ## Fluxos principais
14
-
15
- ### Controle manual de playtest
16
-
17
- ```
18
- "Inicie o jogo em modo Play (F5)."
19
- "Pare o playtest atual."
20
- ```
21
-
22
- Fluxo tipico: `play` -> `play_status` -> `stop`.
23
-
24
- ### Executar um teste automatizado
25
-
26
- ```
27
- "Escreva e execute um teste que verifique se o SpawnLocation esta posicionado corretamente."
28
- ```
29
-
30
- `run_test` injeta o script de teste, inicia o playtest automaticamente, coleta logs e faz a limpeza.
31
-
32
- ### Validacao estilo CI
33
-
34
- ```
35
- "Execute um teste em modo Run (F8) que verifique se o NPC chega ao objetivo e me mostre os logs se falhar."
36
- ```
37
-
38
- Use `run_test` com `mode: "run"` para validacoes focadas no servidor.
39
-
40
- ## Maquina de estados do playtest
41
-
42
- ```text
43
- Edit --play--> Running --stop--> Edit
44
- | ^
45
- pause |
46
- | |
47
- v |
48
- Paused --resume--> Running
49
- ```
50
-
51
- | Estado | Acoes disponiveis |
52
- |--------|-------------------|
53
- | `edit` | `play` |
54
- | `running` | `stop`, `pause` (apenas modo Run) |
55
- | `paused` | `resume`, `stop` |
56
-
57
- - Modo Play (F5): simulacao de cliente + servidor, sem pausa ou retomada
58
- - Modo Run (F8): simulacao apenas de servidor, com pausa e retomada
59
-
60
- ## Fluxo de `run_test`
61
-
62
- `run_test` orquestra estas etapas automaticamente:
63
-
64
- ### 1. Preparacao
65
-
66
- - Ler informacoes do place com `place_info`
67
- - Limpar o buffer de logs existente
68
-
69
- ### 2. Injecao do script
70
-
71
- - Criar `ServerScriptService.__MCP_TestRunner` com um script de teste encapsulado
72
- - O wrapper cuida dos sinais `START` e `FINISHED` e dos tracebacks de erro
73
-
74
- ### 3. Execucao e monitoramento
75
-
76
- - Iniciar o playtest em modo Play ou Run
77
- - Consultar logs a cada 500 ms
78
- - Finalizar quando `[WEPPY_TEST]:FINISHED` for detectado
79
- - Parar automaticamente ao atingir timeout (60 segundos por padrao, 300 no maximo)
80
-
81
- ### 4. Limpeza
82
-
83
- - Parar o playtest automaticamente
84
- - Excluir o script de teste injetado
85
- - Coletar os logs finais
86
-
87
- ### 5. Escrita de relatorios
88
-
89
- Os relatorios e logs sao gravados em `{projectRoot}/weppy-project-sync/place_XXXXX/tests/YYYYMMDD-HHmmss/`.
90
-
91
- ```text
92
- {projectRoot}/weppy-project-sync/place_XXXXX/tests/YYYYMMDD-HHmmss/
93
- ├── test-report.md
94
- └── test-log.txt
95
- ```
96
-
97
- Exemplo de `test-report.md`:
98
-
99
- ```markdown
100
- # Test Report
101
-
102
- - Status: passed
103
- - Test Name: spawn_location_test
104
- - Mode: run
105
- - Place ID: 123456
106
- - Duration (ms): 1523
107
- - Total Logs: 12
108
- - Signal Count: 2
109
-
110
- ## Signals
111
-
112
- - START: 2026-03-12T10:30:00.000Z
113
- - FINISHED: 2026-03-12T10:30:01.523Z
114
- ```
115
-
116
- ## Referencia de acoes
117
-
118
- | Acao | Descricao | Parametros | Tier |
119
- |------|-----------|------------|------|
120
- | `play` | Iniciar playtest em modo Play (F5) ou Run (F8) | `mode`: `"play"` \| `"run"` | Pro |
121
- | `stop` | Parar o playtest atual | - | Pro |
122
- | `pause` | Pausar um playtest em modo Run | - | Pro |
123
- | `resume` | Retomar um playtest pausado em modo Run | - | Pro |
124
- | `play_status` | Obter o estado do playtest e as acoes disponiveis | - | Pro |
125
- | `run_test` | Injetar script de teste, executar playtest, coletar logs e escrever relatorios | `script` (obrigatorio), `test_name`, `mode`, `timeout` | Pro |
126
-
127
- ### Parametros de `run_test`
128
-
129
- | Parametro | Tipo | Obrigatorio | Descricao |
130
- |-----------|------|:-----------:|-----------|
131
- | `script` | string | ✅ | Corpo do codigo Luau de teste a executar |
132
- | `test_name` | string | - | Nome exibido no relatorio |
133
- | `mode` | `"play"` \| `"run"` | - | Modo de playtest, padrao `"play"` |
134
- | `timeout` | number | - | Timeout em segundos, padrao 60, maximo 300 |
135
-
136
- ## Documentos relacionados
137
-
138
- - [Sistema e depuracao](system-and-debugging.md) - acoes de conexao e gerenciamento de logs
139
- - [Scripts e execucao de codigo](scripting.md) - escrever scripts e executar Luau
140
- - [Lista completa de tools](overview.md)
@@ -1,66 +0,0 @@
1
- # Scripts e execucao de codigo
2
-
3
- > Gerencie o codigo-fonte de scripts e execute Luau arbitrario dentro do Roblox Studio.
4
-
5
- ## Tools incluidas
6
-
7
- | Tool | Tier | Descricao |
8
- |------|:----:|-----------|
9
- | `manage_scripts` | Misto | Criar, ler, editar, buscar e analisar dependencias de scripts |
10
- | `execute_luau` | Pro | Executar Luau arbitrario no sandbox do Roblox Studio |
11
-
12
- ## Fluxos principais
13
-
14
- ### Editar um script
15
-
16
- ```
17
- "Altere maxPlayers de 12 para 24 no script GameManager dentro de ServerScriptService."
18
- ```
19
-
20
- Use `manage_scripts.search` para encontrar a linha correta e `manage_scripts.edit_replace` para atualiza-la.
21
-
22
- ### Refatorar varios scripts (Pro)
23
-
24
- ```
25
- "Substitua OldModule por NewModule em todos os scripts."
26
- ```
27
-
28
- Use `manage_scripts.replace` para aplicar a mudanca em varios scripts em uma solicitacao.
29
-
30
- ### Inspecionar dados de runtime (Pro)
31
-
32
- ```
33
- "Calcule a media de Health de todos os Humanoid que estao em Workspace."
34
- ```
35
-
36
- Use `execute_luau` para rodar Luau personalizado e ler dados do runtime atual.
37
-
38
- ## Referencia de acoes
39
-
40
- ### Manage Scripts (Misto)
41
-
42
- | Acao | Descricao | Tier |
43
- |------|-----------|------|
44
- | `get_source` | Obter codigo-fonte do script | Basic |
45
- | `set_source` | Definir codigo-fonte do script | Basic |
46
- | `create` | Criar um novo script | Basic |
47
- | `delete` | Excluir um script | Basic |
48
- | `edit_replace` | Substituir linhas especificas em um script | Basic |
49
- | `edit_insert` | Inserir linhas em uma posicao | Basic |
50
- | `edit_delete` | Excluir linhas especificas | Basic |
51
- | `search` | Buscar texto em scripts | Basic |
52
- | `get_dependencies` | Obter dependencias de um script | Basic |
53
- | `replace` | Substituicao em massa em scripts | Pro |
54
-
55
- ### Execute Luau (Pro)
56
-
57
- Executa Luau arbitrario dentro do sandbox do Roblox Studio.
58
-
59
- - Servicos bloqueados: `HttpService`, `DataStoreService`, `MessagingService`
60
- - APIs inacessiveis: `CoreGui`, `CorePackages`
61
-
62
- ## Documentos relacionados
63
-
64
- - [Instancias e propriedades](instances-and-properties.md) - criar ou mover instancias de script
65
- - [Playtest e testes automatizados](playtest.md) - injetar e executar scripts de teste
66
- - [Lista completa de tools](overview.md)
@@ -1,93 +0,0 @@
1
- # Sistema e depuracao
2
-
3
- > Verifique a conexao, gerencie logs, controle a selecao do Studio e execute lotes para fluxos de depuracao.
4
-
5
- ## Tools incluidas
6
-
7
- | Tool | Tier | Descricao |
8
- |------|:----:|-----------|
9
- | `system_info` | Misto | `ping`, `connection`, `usage`, `place_info`, `services`, `studio_settings` |
10
- | `manage_logs` | Basic | Consultar logs, limpar buffers e filtrar erros recentes |
11
- | `manage_selection` | Misto | Ler, substituir e monitorar a selecao do Studio |
12
- | `batch_execute` | Pro | Executar varios comandos em um unico lote |
13
-
14
- > Para as acoes de playtest de `system_info`, como `play`, `stop` e `run_test`, consulte [Playtest e testes automatizados](playtest.md).
15
-
16
- ## Fluxos principais
17
-
18
- ### Verificar a conexao
19
-
20
- ```
21
- "Confira se o Studio esta conectado corretamente."
22
- ```
23
-
24
- Use `system_info.ping` para uma verificacao rapida.
25
-
26
- ### Depurar erros recentes
27
-
28
- ```
29
- "Mostre os erros mais recentes."
30
- ```
31
-
32
- Use `manage_logs.errors` para obter apenas erros recentes. `manage_logs.get` tambem suporta consulta incremental com cursor `sinceSeq`.
33
-
34
- ### Executar um fluxo em lote (Pro)
35
-
36
- ```
37
- "Deixe todos os Part do Workspace vermelhos e depois foque a camera no primeiro."
38
- ```
39
-
40
- Use `batch_execute` para agrupar varios comandos em uma unica solicitacao.
41
-
42
- ## Referencia de acoes
43
-
44
- ### System Info (Misto)
45
-
46
- | Acao | Descricao | Tier |
47
- |------|-----------|------|
48
- | `ping` | Testar a conexao | Basic |
49
- | `connection` | Obter informacoes de conexao do servidor e plugin | Basic |
50
- | `usage` | Obter o tier atual (`basic` ou `pro`) | Basic |
51
- | `place_info` | Obter Place ID, nome e criador | Pro |
52
- | `services` | Listar todos os servicos Roblox | Pro |
53
- | `studio_settings` | Obter preferencias do Studio | Pro |
54
-
55
- ### Manage Logs (Basic)
56
-
57
- | Acao | Descricao | Tier |
58
- |------|-----------|------|
59
- | `get` | Obter logs filtrados com suporte opcional ao cursor `sinceSeq` | Basic |
60
- | `clear` | Limpar o buffer de logs | Basic |
61
- | `errors` | Obter apenas erros recentes | Basic |
62
-
63
- ### Manage Selection (Misto)
64
-
65
- | Acao | Descricao | Tier |
66
- |------|-----------|------|
67
- | `get` | Obter a selecao atual | Basic |
68
- | `set` | Substituir a selecao atual | Basic |
69
- | `clear` | Limpar a selecao | Basic |
70
- | `cached` | Obter a selecao em cache sem round-trip | Basic |
71
- | `context` | Obter contexto detalhado com codigo-fonte e propriedades | Pro |
72
- | `details` | Obter detalhes hierarquicos com ancestrais e descendentes | Pro |
73
- | `add` | Adicionar itens a selecao | Pro |
74
- | `remove` | Remover itens da selecao | Pro |
75
- | `watch` | Monitorar mudancas de selecao | Pro |
76
-
77
- ### Manage Context (Basic)
78
-
79
- | Acao | Descricao | Tier |
80
- |------|-----------|------|
81
- | `begin` | Inicia um contexto de execucao estruturado para o escopo atual de sessao/place | Basic |
82
- | `update` | Atualiza a intencao, as areas afetadas ou os metadados de replay do contexto ativo | Basic |
83
- | `end` | Encerra o contexto de execucao ativo e persiste o snapshot final | Basic |
84
-
85
- ### Batch Execute (Pro)
86
-
87
- Executa varios comandos em um unico lote. Cada comando inclui nome da tool e argumentos, roda em ordem e pode continuar apos erros se configurado.
88
-
89
- ## Documentos relacionados
90
-
91
- - [Playtest e testes automatizados](playtest.md) - acoes de playtest em `system_info`
92
- - [Scripts e execucao de codigo](scripting.md) - executar Luau para investigacao e depuracao
93
- - [Lista completa de tools](overview.md)
@@ -1,102 +0,0 @@
1
- # Mundo e ambiente
2
-
3
- > Construa e inspecione o mundo do jogo com lighting, terrain, consultas espaciais e ferramentas de camera.
4
-
5
- ## Tools incluidas
6
-
7
- | Tool | Tier | Descricao |
8
- |------|:----:|-----------|
9
- | `manage_lighting` | Pro | Configura Lighting, Atmosphere, Sky e hora do dia |
10
- | `manage_terrain` | Pro | Gera e edita terrain, incluindo dados voxel |
11
- | `spatial_query` | Pro | Raycasts, busca de solo, validacao de posicionamento e mapas de altura |
12
- | `manage_camera` | Basic | Inspeciona o estado da camera, move o foco e sugere visoes |
13
-
14
- ## Fluxos principais
15
-
16
- ### Definir a atmosfera (Pro)
17
-
18
- ```
19
- "Mude o mapa para um clima de por do sol com ceu laranja, nevoa mais densa e horario 18:00."
20
- ```
21
-
22
- Use `manage_lighting.time` para a hora, `manage_lighting.atmosphere` para a nevoa e `manage_lighting.sky` para o ceu.
23
-
24
- ### Construir terrain (Pro)
25
-
26
- ```
27
- "Crie uma colina de grama com raio 200 no centro do mapa e coloque agua ao redor."
28
- ```
29
-
30
- Use `manage_terrain.fill_ball` para a colina e `manage_terrain.fill_block` para a agua ao redor.
31
-
32
- ### Validar posicionamento (Pro)
33
-
34
- ```
35
- "Encontre uma area plana onde eu possa colocar este predio."
36
- ```
37
-
38
- Use `spatial_query.find_flat` para achar candidatos, `spatial_query.check_placement` para valida-los e `manage_camera.focus_position` para inspecao visual.
39
-
40
- ## Referencia de acoes
41
-
42
- ### Manage Lighting (Pro)
43
-
44
- | Acao | Descricao | Tier |
45
- |------|-----------|------|
46
- | `lighting` | Definir propriedades do servico Lighting | Pro |
47
- | `atmosphere` | Definir propriedades de Atmosphere | Pro |
48
- | `sky` | Definir propriedades de Sky | Pro |
49
- | `terrain_props` | Definir propriedades visuais e de agua de Terrain | Pro |
50
- | `time` | Definir hora do dia | Pro |
51
-
52
- ### Manage Terrain (Pro)
53
-
54
- | Acao | Descricao | Tier |
55
- |------|-----------|------|
56
- | `fill_block` | Preencher terrain em forma de bloco | Pro |
57
- | `fill_ball` | Preencher terrain em forma de esfera | Pro |
58
- | `fill_cylinder` | Preencher terrain em forma de cilindro | Pro |
59
- | `fill_wedge` | Preencher terrain em forma de cunha | Pro |
60
- | `clear_region` | Limpar terrain em uma regiao | Pro |
61
- | `clear_bounds` | Limpar terrain dentro de limites | Pro |
62
- | `replace_material` | Substituir material em uma regiao | Pro |
63
- | `colors_get` | Obter cores de material | Pro |
64
- | `colors_set` | Definir cores de material | Pro |
65
- | `read_voxel` | Ler um voxel individual | Pro |
66
- | `read_voxels` | Ler dados voxel em lote | Pro |
67
- | `write_voxels` | Escrever dados voxel em lote | Pro |
68
- | `generate` | Gerar terrain procedural | Pro |
69
- | `smooth` | Suavizar terrain | Pro |
70
-
71
- ### Spatial Query (Pro)
72
-
73
- | Acao | Descricao | Tier |
74
- |------|-----------|------|
75
- | `raycast` | Lancar um unico raio | Pro |
76
- | `find_ground` | Encontrar a posicao do solo abaixo de um ponto | Pro |
77
- | `check_placement` | Verificar se um posicionamento esta livre de colisao | Pro |
78
- | `multi_raycast` | Lancar varios raios em lote | Pro |
79
- | `scan_area` | Gerar um mapa de altura de uma area | Pro |
80
- | `find_flat` | Encontrar areas planas para construir | Pro |
81
- | `find_spawn` | Encontrar posicoes de spawn adequadas | Pro |
82
- | `analyze_walkable` | Analisar uma grade de navegacao | Pro |
83
- | `spatial_map` | Obter todas as posicoes de BasePart | Pro |
84
- | `find_space` | Encontrar espaco vazio para um objeto | Pro |
85
- | `bounds` | Obter caixas delimitadoras de instancias | Pro |
86
- | `snap_grid` | Ajustar uma posicao a grade | Pro |
87
- | `collision` | Verificar colisao AABB | Pro |
88
-
89
- ### Manage Camera (Basic)
90
-
91
- | Acao | Descricao | Tier |
92
- |------|-----------|------|
93
- | `info` | Obter posicao, rotacao, FOV e tamanho do viewport da camera | Basic |
94
- | `focus_path` | Mover a camera para focar uma instancia | Basic |
95
- | `focus_position` | Mover a camera para focar uma posicao | Basic |
96
- | `suggest` | Obter uma visao de camera sugerida para um alvo | Basic |
97
-
98
- ## Documentos relacionados
99
-
100
- - [Instancias e propriedades](instances-and-properties.md) - posicionar objetos do mundo
101
- - [Assets e efeitos](assets-and-effects.md) - adicionar efeitos, audio e animacao
102
- - [Lista completa de tools](overview.md)
@@ -1,47 +0,0 @@
1
- # Troubleshooting
2
-
3
- ## Plugin not connecting
4
-
5
- **Symptom:** "Connection failed" or plugin shows disconnected in Roblox Studio.
6
-
7
- 1. Make sure the MCP server is running: `npx -y @weppy/roblox-mcp`
8
- 2. In Roblox Studio: Plugins tab → WEPPY → Connect
9
- 3. Confirm nothing is blocking `localhost:3002` (firewall, antivirus, VPN)
10
- 4. Try restarting both Roblox Studio and the MCP server
11
-
12
- ## MCP server not found by AI client
13
-
14
- 1. Verify your AI client config uses the correct command: `npx -y @weppy/roblox-mcp`
15
- 2. Ensure Node.js >= 18 is installed: `node --version`
16
- 3. On Windows, try running your terminal as Administrator if permission errors appear
17
- 4. Check the client-specific setup guide in [Installation](en/installation/README.md)
18
-
19
- ## "Pro feature required" error
20
-
21
- The action you're requesting requires the Pro tier.
22
- See [Pro Upgrade Guide](https://weppyai.com/en/plans) for details.
23
-
24
- ## Sync not working
25
-
26
- 1. Check sync status: ask AI `manage_sync status`
27
- 2. Ensure the plugin is connected before starting sync
28
- 3. For reverse sync (file → Studio), confirm Pro tier is active
29
- 4. Check that the local sync folder exists and has write permissions
30
-
31
- ## Common error messages
32
-
33
- | Error | Cause | Fix |
34
- |-------|-------|-----|
35
- | `ECONNREFUSED localhost:3002` | MCP server not running | Run `npx -y @weppy/roblox-mcp` |
36
- | `Timeout waiting for plugin` | Studio plugin not connected | Click Connect in plugin panel |
37
- | `Rate limit exceeded` | Over 450 requests/min | Reduce or batch requests |
38
- | `Forbidden path` | Accessing CoreGui/CorePackages | Use valid instance paths only |
39
- | `Place ID mismatch` | Wrong place connected | Reconnect from correct Studio session |
40
-
41
- ## Still stuck?
42
-
43
- [Open a Discussion](https://github.com/hope1026/weppy-roblox-mcp/discussions) and include:
44
- - OS and Node.js version
45
- - AI client and version
46
- - Error message or logs
47
- - Steps you already tried
@@ -1 +0,0 @@
1
- import{d as w,r,f as z,D as B,e as H,g as O,h as D,a as R,u as M,j as e,T as x,A as $,S as G}from"./index-BfvSPSNj.js";import{I as c}from"./InfoLabel-DrK7vhO-.js";function W(){const{level:t}=w(),[l,L]=r.useState(null),[u,a]=r.useState(null),[S,v]=r.useState(!1),[b,P]=r.useState(!0),[A,_]=r.useState(!1),[k,m]=r.useState(null),g="gumroad",h=t==="disconnected",p=r.useCallback(n=>{n&&a(o=>({...o,...n,maskedKey:n.maskedKey??(o==null?void 0:o.maskedKey),provider:n.provider??(o==null?void 0:o.provider)??g}))},[g]),f=r.useCallback(n=>{if(!n){a(null);return}a({...n,provider:n.provider??g})},[g]),N=r.useCallback(async()=>{try{return await z(g)}catch{return null}},[g]);r.useEffect(()=>{let n=!1;async function o(){try{const[d,T]=await Promise.all([R.get("/api/dashboard/settings").catch(()=>null),N()]);if(n)return;d&&L(d),T&&p(T)}catch{}finally{n||P(!1)}}return o(),()=>{n=!0}},[N,p]),r.useEffect(()=>{const n=new B;n.connect();const o=n.on("license",d=>{N().then(T=>{if(T){if((d==null?void 0:d.cleared)===!0){f(T);return}p(T)}})});return()=>{o(),n.disconnect()}},[N,p,f]);const j=r.useCallback((n,o)=>{m(n??o)},[]),E=r.useCallback(async n=>{if(h)return!1;if(!n.trim())return m("License key is required."),!1;_(!0);try{const o=await H({provider:g,licenseKey:n.trim()});return p(o.license),j(o.message,o.ok?"License updated.":"License activation failed."),o.ok}catch{return m("License activation failed."),!1}finally{_(!1)}},[j,h,g,p]),y=r.useCallback(async()=>{if(!h){_(!0);try{const n=await O({provider:g});p(n.license),j(n.message,n.ok?"License updated.":"License refresh failed.")}catch{m("License refresh failed.")}finally{_(!1)}}},[j,h,g,p]),C=r.useCallback(async()=>{if(!h){_(!0);try{const n=await D({provider:g});f(n.license),j(n.message,n.ok?"License reset.":"License reset failed.")}catch{m("License reset failed.")}finally{_(!1)}}},[j,h,g,f]),i=r.useCallback(async(n,o)=>{if(l){L(d=>d&&{...d,hot:{...d.hot,[n]:o}}),v(!0);try{await R.patch("/api/dashboard/settings",{[n]:o})}catch{L(d=>d&&{...d,hot:{...d.hot,[n]:l.hot[n]}})}finally{v(!1)}}},[l]);return{settings:l,license:u,saving:S,licenseProvider:g,licenseControlsDisabled:h,licenseSubmitting:A,licenseMessage:k,activateLicense:E,refreshLicense:y,resetLicense:C,updateHotSetting:i,loading:b}}const Y="_page_vbvzx_2",F="_card_vbvzx_10",q="_licenseCardPro_vbvzx_17",U="_cardHeader_vbvzx_28",K="_headerBadge_vbvzx_42",V="_headerBadgeLive_vbvzx_53",Q="_licenseGrid_vbvzx_59",X="_statusDot_vbvzx_77",J="_statusActive_vbvzx_86",Z="_statusGrace_vbvzx_91",ee="_statusInactive_vbvzx_96",te="_statusError_vbvzx_100",se="_proBadge_vbvzx_105",ie="_upgradeLink_vbvzx_119",ne="_licenseControls_vbvzx_133",ae="_licenseControlRow_vbvzx_142",le="_licenseField_vbvzx_149",oe="_licenseFieldGrow_vbvzx_155",ce="_controlLabel_vbvzx_160",re="_textInput_vbvzx_166",de="_actionBtn_vbvzx_182",ge="_licenseMessage_vbvzx_204",ue="_licenseNotice_vbvzx_211",he="_licenseNoticeInfo_vbvzx_221",ve="_licenseNoticeWarning_vbvzx_227",pe="_licenseNoticeMuted_vbvzx_233",be="_settingRow_vbvzx_239",xe="_settingLabel_vbvzx_253",_e="_settingControl_vbvzx_260",me="_select_vbvzx_269",je="_numberInput_vbvzx_287",Le="_toggleSwitch_vbvzx_305",fe="_toggleInput_vbvzx_312",Ne="_toggleTrack_vbvzx_320",Ce="_toggleThumb_vbvzx_342",Te="_savedIndicator_vbvzx_391",Pe="_savedIndicatorHidden_vbvzx_402",Ee="_coldGrid_vbvzx_407",ye="_coldHint_vbvzx_425",Se="_langRow_vbvzx_434",Ae="_loading_vbvzx_447",ke="_unit_vbvzx_456",s={page:Y,card:F,licenseCardPro:q,cardHeader:U,headerBadge:K,headerBadgeLive:V,licenseGrid:Q,statusDot:X,statusActive:J,statusGrace:Z,statusInactive:ee,statusError:te,proBadge:se,upgradeLink:ie,licenseControls:ne,licenseControlRow:ae,licenseField:le,licenseFieldGrow:oe,controlLabel:ce,textInput:re,actionBtn:de,licenseMessage:ge,licenseNotice:ue,licenseNoticeInfo:he,licenseNoticeWarning:ve,licenseNoticeMuted:pe,settingRow:be,settingLabel:xe,settingControl:_e,select:me,numberInput:je,toggleSwitch:Le,toggleInput:fe,toggleTrack:Ne,toggleThumb:Ce,savedIndicator:Te,savedIndicatorHidden:Pe,coldGrid:Ee,coldHint:ye,langRow:Se,loading:Ae,unit:ke},Ie={en:"English",ko:"한국어",es:"Español","pt-br":"Português (BR)",ja:"日本語",id:"Bahasa Indonesia"},Re=["debug","info","warn","error"];function we(t){return t==="active"?s.statusActive:t==="grace"?s.statusGrace:t==="invalid"||t==="revoked"?s.statusError:s.statusInactive}function ze(t,l){return t.refreshBlockedReason==="missing_session_token"?{label:l("settings.license.status.activationRequired","Activation Required"),tooltip:l("settings.license.status.activationRequired.tooltip","Manual license activation is required before WEPPY Dashboard can refresh this status."),detail:l("settings.license.detail.missingSessionToken","Refresh is blocked because the current session token is missing."),detailTone:s.licenseNoticeWarning}:t.statusDetail==="active_cancel_pending"?{label:l("settings.license.active","Active"),tooltip:l("settings.license.status.activeCancelPending.tooltip","Cancellation is pending, but Pro access remains active until the current billing period ends."),detail:l("settings.license.detail.cancelPending","Cancellation is scheduled. Pro access remains active until the current billing period ends."),detailTone:s.licenseNoticeInfo}:t.statusDetail==="grace_provider_unavailable"?{label:l("settings.license.status.grace","Grace"),tooltip:l("settings.license.status.grace.tooltip","Provider verification is temporarily unavailable, but Pro access remains active during the grace period."),detail:l("settings.license.detail.graceProviderUnavailable","Provider unavailable. Pro access remains active during grace mode."),detailTone:s.licenseNoticeInfo}:t.statusDetail==="grace_expired"||t.statusDetail==="grace_payment_failed"?{label:l("settings.license.status.grace","Grace"),tooltip:l("settings.license.status.graceBilling.tooltip","Pro access is still available during a billing-related grace period."),detail:l("settings.license.detail.graceBilling","Pro access remains available during a billing grace period."),detailTone:s.licenseNoticeInfo}:{label:l(`settings.license.${t.status}`,t.status),tooltip:l(`settings.license.${t.status}.tooltip`,"Current license activation state."),detail:t.refreshRequired?l("settings.license.detail.refreshRecommended","License verification should be refreshed soon."):null,detailTone:s.licenseNoticeMuted}}function I({checked:t,onChange:l,testId:L,ariaLabel:u}){return e.jsxs("label",{className:s.toggleSwitch,"data-testid":L,children:[e.jsx("input",{type:"checkbox",className:s.toggleInput,checked:t,"aria-label":u,onChange:a=>l(a.target.checked)}),e.jsx("span",{className:s.toggleTrack,"aria-hidden":"true",children:e.jsx("span",{className:s.toggleThumb})})]})}function Oe(){const{t,selectedLocale:l,setLocale:L}=M(),{settings:u,license:a,licenseProvider:S,licenseControlsDisabled:v,licenseSubmitting:b,licenseMessage:P,activateLicense:A,refreshLicense:_,resetLicense:k,updateHotSetting:m,loading:g}=W(),[h,p]=r.useState(null),[f,N]=r.useState(""),j=a?ze(a,t):null,E=(a==null?void 0:a.tier)==="pro",y=(a==null?void 0:a.tier)==="pro"?a.maskedKey:void 0,C=r.useCallback(async(i,n)=>{await m(i,n),p(i),setTimeout(()=>p(o=>o===i?null:o),2e3)},[m]);return g?e.jsx("div",{className:s.page,children:e.jsx("div",{className:s.loading,children:t("common.loading")})}):e.jsxs("div",{className:s.page,children:[e.jsxs("div",{"data-testid":"settings-license-card",className:[s.card,(a==null?void 0:a.tier)==="pro"?s.licenseCardPro:""].filter(Boolean).join(" "),children:[e.jsxs("div",{className:s.cardHeader,children:[e.jsx(c,{label:t("settings.license.title","License"),tooltip:t("settings.license.title.tooltip","Current license status and subscription tier.")}),e.jsx(x,{text:v?t("settings.license.disconnected.tooltip","Reconnect to the MCP server to manage license actions from WEPPY Dashboard."):t("settings.license.live.tooltip","License actions are sent to the MCP server immediately."),children:e.jsx("span",{className:`${s.headerBadge} ${v?"":s.headerBadgeLive}`,children:v?t("settings.license.disconnected","Disconnected"):t("settings.general.liveApply","Live Apply")})})]}),e.jsxs(e.Fragment,{children:[a?e.jsxs(e.Fragment,{children:[(()=>{const i=j;return e.jsxs(e.Fragment,{children:[e.jsxs("dl",{className:s.licenseGrid,children:[e.jsx("dt",{children:e.jsx(c,{label:t("settings.license.status","Status"),tooltip:t("settings.license.status.tooltip","Current license activation state.")})}),e.jsxs("dd",{children:[e.jsx("span",{className:`${s.statusDot} ${we(a.status)}`}),e.jsx(x,{text:(i==null?void 0:i.tooltip)??t(`settings.license.${a.status}.tooltip`,"Current license activation state."),children:(i==null?void 0:i.label)??t(`settings.license.${a.status}`,a.status)})]}),e.jsx("dt",{children:e.jsx(c,{label:t("settings.license.tier","Tier"),tooltip:t("settings.license.tier.tooltip","Current subscription tier for available WEPPY Dashboard features.")})}),e.jsx("dd",{className:a.tier==="pro"?s.proBadge:"",children:e.jsx(x,{text:t(`tier.${a.tier}.tooltip`,"Available feature set for the connected license."),children:a.tier==="pro"?t("tier.pro","Pro"):t("tier.basic","Basic")})}),y&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(c,{label:t("settings.license.key","Key"),tooltip:t("settings.license.key.tooltip","Masked license key currently loaded by the server.")})}),e.jsx("dd",{children:e.jsx(x,{text:t("settings.license.keyValue.tooltip","Masked license key currently loaded by the server."),children:y})})]}),a.provider&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(c,{label:t("settings.license.provider","Provider"),tooltip:t("settings.license.provider.tooltip","License provider used to validate this key.")})}),e.jsx("dd",{children:e.jsx(x,{text:t("settings.license.providerValue.tooltip","License provider used to validate this key."),children:a.provider})})]})]}),(i==null?void 0:i.detail)&&e.jsx("p",{className:`${s.licenseNotice} ${i.detailTone}`,children:a.refreshBlockedReason==="missing_session_token"?t("settings.license.detail.manualActivation","Manual activation required to restore Pro access."):i.detail}),a.refreshBlockedReason==="missing_session_token"&&e.jsx("p",{className:`${s.licenseNotice} ${s.licenseNoticeMuted}`,children:i==null?void 0:i.detail})]})})(),a.tier==="basic"&&e.jsx("a",{className:s.upgradeLink,href:"https://gum.co/u/din5in7h",target:"_blank",rel:"noopener noreferrer",children:t("tier.upgrade")})]}):e.jsx("div",{className:s.loading,children:t("settings.license.unavailable")}),e.jsxs("div",{className:s.licenseControls,children:[e.jsxs("div",{className:s.licenseControlRow,children:[e.jsxs("label",{className:s.licenseField,children:[e.jsx("span",{className:s.controlLabel,children:e.jsx(c,{label:t("settings.license.provider","Provider"),tooltip:t("settings.license.provider.tooltip","License provider used to validate this key.")})}),e.jsx("select",{"aria-label":t("settings.license.provider","Provider"),className:s.select,value:S,disabled:v||b,onChange:()=>{},children:e.jsx("option",{value:"gumroad",children:"gumroad"})})]}),e.jsx("button",{type:"button",className:s.actionBtn,disabled:v||b||!E,onClick:()=>{_()},children:b?t("common.loading"):t("settings.license.refresh","Refresh License")}),e.jsx("button",{type:"button",className:s.actionBtn,disabled:v||b||!E,onClick:()=>{k()},children:b?t("common.loading"):t("settings.license.reset","Reset License")})]}),e.jsxs("div",{className:s.licenseControlRow,children:[e.jsxs("label",{className:`${s.licenseField} ${s.licenseFieldGrow}`,children:[e.jsx("span",{className:s.controlLabel,children:e.jsx(c,{label:t("settings.license.keyInput","License Key"),tooltip:t("settings.license.key.tooltip","Masked license key currently loaded by the server.")})}),e.jsx("input",{"aria-label":t("settings.license.keyInput","License Key"),className:s.textInput,type:"text",value:f,disabled:v||b,onChange:i=>N(i.target.value)})]}),e.jsx("button",{type:"button",className:s.actionBtn,disabled:v||b,onClick:()=>{(async()=>await A(f)&&N(""))()},children:b?t("common.loading"):t("settings.license.activate","Activate License")})]}),P&&e.jsx("p",{className:s.licenseMessage,children:P})]})]})]}),e.jsxs("div",{className:s.card,children:[e.jsxs("div",{className:s.cardHeader,children:[e.jsx(c,{label:t("settings.general.title","General Settings"),tooltip:t("settings.general.title.tooltip","Hot settings that apply immediately when changed.")}),e.jsx(x,{text:t("settings.general.liveApply.tooltip","Changes in this section are applied immediately without a separate save button."),children:e.jsx("span",{className:`${s.headerBadge} ${s.headerBadgeLive}`,children:t("settings.general.liveApply","Live Apply")})})]}),u?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:s.settingRow,children:[e.jsx("span",{className:s.settingLabel,children:e.jsx(c,{label:t("settings.general.logLevel","Log Level"),tooltip:t("settings.general.logLevel.tooltip","Sets how much detail WEPPY Dashboard writes to its logs.")})}),e.jsxs("div",{className:s.settingControl,children:[e.jsx("select",{className:s.select,value:u.hot.LOG_LEVEL,onChange:i=>C("LOG_LEVEL",i.target.value),children:Re.map(i=>e.jsx("option",{value:i,children:i},i))}),h==="LOG_LEVEL"&&e.jsx("span",{className:s.savedIndicator,children:t("settings.general.applied")})]})]}),e.jsxs("div",{className:s.settingRow,children:[e.jsx("span",{className:s.settingLabel,children:e.jsx(c,{label:t("settings.general.localHistory","Tool History Recording"),tooltip:t("settings.general.localHistory.tooltip","Stores local tool execution history for the WEPPY Dashboard history views.")})}),e.jsxs("div",{className:s.settingControl,children:[e.jsx("span",{className:`${s.savedIndicator} ${h==="ENABLE_LOCAL_HISTORY"?"":s.savedIndicatorHidden}`,children:t("settings.general.applied","Applied")}),e.jsx(I,{checked:u.hot.ENABLE_LOCAL_HISTORY,ariaLabel:t("settings.general.localHistory","Tool History Recording"),testId:"settings-toggle-enable-local-history",onChange:i=>C("ENABLE_LOCAL_HISTORY",i)})]})]}),e.jsxs("div",{className:s.settingRow,children:[e.jsx("span",{className:s.settingLabel,children:e.jsx(c,{label:t("settings.general.localStatistics","Tool Statistics Collection"),tooltip:t("settings.general.localStatistics.tooltip","Aggregates local usage statistics for WEPPY Dashboard reporting.")})}),e.jsxs("div",{className:s.settingControl,children:[e.jsx("span",{className:`${s.savedIndicator} ${h==="ENABLE_LOCAL_STATISTICS"?"":s.savedIndicatorHidden}`,children:t("settings.general.applied","Applied")}),e.jsx(I,{checked:u.hot.ENABLE_LOCAL_STATISTICS,ariaLabel:t("settings.general.localStatistics","Tool Statistics Collection"),testId:"settings-toggle-enable-local-statistics",onChange:i=>C("ENABLE_LOCAL_STATISTICS",i)})]})]}),e.jsxs("div",{className:s.settingRow,children:[e.jsx("span",{className:s.settingLabel,children:e.jsx(c,{label:t("settings.general.contextCapture","Context Capture"),tooltip:t("settings.general.contextCapture.tooltip","When enabled, WEPPY Dashboard records structured execution context for changelog and playtest views.")})}),e.jsxs("div",{className:s.settingControl,children:[e.jsx("span",{className:`${s.savedIndicator} ${h==="ENABLE_CONTEXT_CAPTURE"?"":s.savedIndicatorHidden}`,children:t("settings.general.applied","Applied")}),e.jsx(I,{checked:u.hot.ENABLE_CONTEXT_CAPTURE,ariaLabel:t("settings.general.contextCapture","Context Capture"),testId:"settings-toggle-enable-context-capture",onChange:i=>C("ENABLE_CONTEXT_CAPTURE",i)})]})]}),e.jsxs("div",{className:s.settingRow,children:[e.jsx("span",{className:s.settingLabel,children:e.jsx(c,{label:t("settings.general.requestTimeout","Request Timeout"),tooltip:t("settings.general.requestTimeout.tooltip","Maximum time WEPPY Dashboard waits for a request before it fails.")})}),e.jsxs("div",{className:s.settingControl,children:[e.jsx("input",{type:"number",className:s.numberInput,value:u.hot.REQUEST_TIMEOUT,min:1e3,max:12e4,step:1e3,onChange:i=>{const n=parseInt(i.target.value,10);isNaN(n)||C("REQUEST_TIMEOUT",n)}}),e.jsx(x,{text:t("settings.general.requestTimeout.unit.tooltip","Request timeout is measured in milliseconds."),children:e.jsx("span",{className:s.unit,children:t("settings.general.requestTimeout.unit","ms")})}),h==="REQUEST_TIMEOUT"&&e.jsx("span",{className:s.savedIndicator,children:t("settings.general.applied","Applied")})]})]})]}):e.jsx("div",{className:s.loading,children:t("settings.unavailable")})]}),e.jsxs("div",{className:s.card,children:[e.jsxs("div",{className:s.cardHeader,children:[e.jsx(c,{label:t("settings.cold.title","Server Environment"),tooltip:t("settings.cold.title.tooltip","Read-only server environment values loaded at startup.")}),e.jsx(x,{text:t("settings.readOnly.tooltip","This section shows values that cannot be edited from WEPPY Dashboard."),children:e.jsx("span",{className:s.headerBadge,children:t("settings.readOnly","Read-only")})})]}),u?e.jsxs(e.Fragment,{children:[e.jsxs("dl",{className:s.coldGrid,children:[e.jsx("dt",{children:e.jsx(c,{label:"HTTP_PORT",tooltip:t("settings.cold.httpPort.tooltip","Port number used by the MCP WEPPY Dashboard HTTP server.")})}),e.jsx("dd",{children:u.cold.HTTP_PORT}),e.jsx("dt",{children:e.jsx(c,{label:"HTTP_HOST",tooltip:t("settings.cold.httpHost.tooltip","Host interface that the MCP WEPPY Dashboard HTTP server binds to.")})}),e.jsx("dd",{children:u.cold.HTTP_HOST}),e.jsx("dt",{children:e.jsx(c,{label:"DASHBOARD_AUTO_OPEN",tooltip:t("settings.cold.dashboardAutoOpen.tooltip","Controls whether WEPPY Dashboard opens automatically in the browser when the server starts.")})}),e.jsx("dd",{children:e.jsx(x,{text:t("settings.cold.dashboardAutoOpen.value.tooltip","Current startup behavior for opening WEPPY Dashboard in a browser."),children:String(u.cold.DASHBOARD_AUTO_OPEN)})})]}),e.jsx("p",{className:s.coldHint,children:t("settings.cold.hint","Set via environment variables to change these values.")})]}):e.jsx("div",{className:s.loading,children:t("settings.unavailable")})]}),e.jsxs("div",{className:s.card,children:[e.jsx("div",{className:s.cardHeader,children:e.jsx(c,{label:t("settings.language.title","Language"),tooltip:t("settings.language.title.tooltip","Choose how the WEPPY Dashboard interface text is localized.")})}),e.jsxs("div",{className:s.langRow,children:[e.jsx("label",{children:e.jsx(c,{label:t("settings.language.dashboard","WEPPY Dashboard Language"),tooltip:t("settings.language.dashboard.tooltip","Overrides the WEPPY Dashboard language or follows the system language when set to Auto.")})}),e.jsxs("select",{className:s.select,value:l,onChange:i=>L(i.target.value),children:[e.jsx("option",{value:$,children:t("settings.language.auto","Auto")}),G.map(i=>e.jsx("option",{value:i,children:Ie[i]??i},i))]})]})]})]})}export{Oe as Component};
@@ -1 +0,0 @@
1
- import{r as o,D as S,a as T,f as R,u as j,j as t}from"./index-BfvSPSNj.js";function pe(){const[c,e]=o.useState("basic"),[m,n]=o.useState(0),[p,g]=o.useState(0),[a,i]=o.useState(0),[k,P]=o.useState(!0);o.useEffect(()=>{let _=!1;async function y(){try{return await R("gumroad")}catch{return null}}async function C(){var r,b;try{const[u,d]=await Promise.all([y(),T.get("/api/dashboard/tool-stats").catch(()=>null)]);if(_)return;if(u!=null&&u.tier&&e(u.tier),d!=null&&d.tierSummary){const f=((r=d.tierSummary.basic)==null?void 0:r.totalCalls)??0,x=((b=d.tierSummary.pro)==null?void 0:b.totalCalls)??0;i(f),g(x),n(f+x)}}catch{}finally{_||P(!1)}}C();const h=new S;h.connect();const N=h.on("license",()=>{y().then(r=>{!_&&(r!=null&&r.tier)&&e(r.tier)})});return()=>{_=!0,N(),h.disconnect()}},[]);const w=m>0?p/m*100:0;return{tier:c,proUsagePercent:w,totalCalls:m,proCalls:p,basicCalls:a,loading:k}}const O=[{name:"query_instances",description:"Query Roblox instances: get, children, find child/descendant, wait for child, class info, search by name/class. [PRO] file_tree, project_structure, descendants, ancestors, search by property/tag.",basic:["get","children","find_child","find_descendant","wait_for_child","class_info","search_name","search_class"],pro:["search_property","search_tag","file_tree","project_structure","descendants","ancestors"]},{name:"mutate_instances",description:"Create, delete, clone, move, rename, or pivot instances. [PRO] create_tree, mass_create, mass_delete, mass_duplicate, smart_duplicate.",basic:["create","create_with_props","delete","clone","move","rename","pivot"],pro:["create_tree","mass_create","mass_delete","mass_duplicate","smart_duplicate"]},{name:"manage_properties",description:"Get/set properties, attributes, and tags on instances. [PRO] set_calculated, set_relative, mass_set, mass_get, modify_children.",basic:["get","set","get_all","set_multiple","get_attr","set_attr","get_all_attrs","delete_attr","add_tag","remove_tag","check_tag","get_tags","get_tagged"],pro:["set_calculated","set_relative","mass_set","mass_get","modify_children"]},{name:"manage_scripts",description:"Manage script source code: read, write, create, delete, edit lines, search. [PRO] replace across scripts.",basic:["get_source","set_source","create","delete","edit_replace","edit_insert","edit_delete","search","get_dependencies"],pro:["replace"]},{name:"manage_lighting",description:"[PRO] Configure environment: lighting, atmosphere, sky, terrain properties, time of day.",basic:[],pro:["lighting","atmosphere","sky","terrain_props","time"]},{name:"manage_selection",description:"Get, set, or clear selection. [PRO] context, details, add/remove items, watch changes.",basic:["get","set","clear","cached"],pro:["context","details","add","remove","watch"]},{name:"manage_camera",description:"Camera operations: get info, focus on instance by path or position, get suggested view.",basic:["info","focus_path","focus_position","suggest"],pro:[]},{name:"manage_tween",description:"[PRO] Tween service: create, play, pause, cancel tweens for smooth animations.",basic:[],pro:["create","play","pause","cancel"]},{name:"manage_audio",description:"[PRO] Audio management: play, stop, pause, resume sounds. Set audio listener.",basic:[],pro:["play","stop","pause","resume","set_listener"]},{name:"manage_animation",description:"[PRO] Animation: load, play, stop animations. Get animation tracks from humanoid/controller.",basic:[],pro:["load","play","stop","get_tracks"]},{name:"manage_physics",description:"[PRO] Physics collision groups: register, set collidable between groups, list groups.",basic:[],pro:["register_group","set_collidable","get_groups"]},{name:"manage_effects",description:"[PRO] Particle effects: emit particles, clear all particles, toggle effect enabled state.",basic:[],pro:["emit","clear","toggle"]},{name:"manage_terrain",description:"[PRO] Terrain operations: fill shapes, clear regions, replace materials, manage colors, read/write voxels, generate procedural terrain, smooth terrain.",basic:[],pro:["fill_block","fill_ball","fill_cylinder","fill_wedge","clear_region","clear_bounds","replace_material","colors_get","colors_set","read_voxel","read_voxels","write_voxels","generate","smooth"]},{name:"spatial_query",description:"[PRO] Spatial queries: raycast, find ground, check placement, multi-raycast, scan area, find flat areas, find spawn positions, analyze walkable, spatial map, find empty space, get bounds, snap to grid, check collision.",basic:[],pro:["raycast","find_ground","check_placement","multi_raycast","scan_area","find_flat","find_spawn","analyze_walkable","spatial_map","find_space","bounds","snap_grid","collision"]},{name:"manage_assets",description:"[PRO] Asset management: insert models by ID, get asset info, search creator store, insert free models/packages, export selection.",basic:[],pro:["insert","info","search","search_insert","insert_free","insert_package","export"]},{name:"manage_sync",description:"[PRO] Project sync management: status, history, direction settings, read/write synced files.",basic:[],pro:["status_current_place","history","directions","read_file","write_file","progress"]},{name:"workspace_state",description:"[PRO] Workspace state: full sync, snapshot, recent changes, viewport info, clear history, metadata, scripts, selection info, clear cache.",basic:[],pro:["sync","snapshot","changes","viewport","clear_history","metadata","scripts","selection_info","clear_cache"]},{name:"manage_logs",description:"Output logs: get filtered logs, poll incrementally with sinceSeq cursor, clear buffer, get recent errors.",basic:["get","clear","errors"],pro:[]},{name:"system_info",description:"System info: ping, connection status, usage tier. [PRO] place info, services list, studio settings, playtest control, automated test runner.",basic:["ping","connection","usage"],pro:["place_info","services","studio_settings","play","stop","pause","resume","play_status","run_test"]},{name:"batch_execute",description:'[PRO] Execute multiple commands in a single batch. Each command is an object with "tool" name and "args". Commands execute sequentially; optionally continue on error.',basic:[],pro:["batch_execute"]},{name:"execute_luau",description:"[PRO] Execute arbitrary Luau code in Roblox Studio sandbox. Blocked services: HttpService, DataStoreService, MessagingService. Cannot access CoreGui/CorePackages.",basic:[],pro:["execute_luau"]}],B={proOnlyTools:13,mixedTools:6,totalBasicActions:51,totalProActions:106},L={tools:O,summary:B},A=new Date("2026-04-30T23:59:59");function v(){return Date.now()<=A.getTime()}const _e={overview:"https://gum.co/u/2nc0fhky",changelog:"https://gum.co/u/wjcnucpy",sync:"https://gum.co/u/p0barnlb",playtest:"https://gum.co/u/kchczjry",tools:"https://gum.co/u/ljmteaed"},D="_tag_1wj0q_2",E="_label_1wj0q_17",q="_code_1wj0q_22",G="_expiry_1wj0q_31",M="_inline_1wj0q_49",$="_centered_1wj0q_54",l={tag:D,label:E,code:q,expiry:G,inline:M,centered:$};function W({variant:c}){const{t:e}=j();return v()?t.jsxs("div",{className:`${l.tag} ${c==="centered"?l.centered:l.inline}`,children:[t.jsx("span",{className:l.label,children:e("tier.promo.discount.context","🎁 Gumroad 결제 시 할인코드 입력:")}),t.jsx("span",{className:l.code,children:e("tier.comparison.discount.code","WEPPY-MCP")}),t.jsx("span",{className:l.expiry,children:e("tier.comparison.discount.expiry","Valid until April 30")})]}):null}const H="_overlay_171mk_2",I="_modal_171mk_13",U="_summaryGrid_171mk_32",z="_summaryCard_171mk_39",Y="_basicCard_171mk_45",F="_proCard_171mk_49",Q="_cardTitle_171mk_54",V="_summarySection_171mk_70",X="_sectionTitle_171mk_78",J="_featureList_171mk_90",K="_summary_171mk_32",Z="_statBasic_171mk_116",ee="_statPro_171mk_120",te="_statMixed_171mk_124",se="_detailHeader_171mk_128",ae="_tableWrap_171mk_137",ie="_table_171mk_137",re="_toolName_171mk_165",ce="_description_171mk_171",ne="_actionList_171mk_176",oe="_none_171mk_184",le="_discountBanner_171mk_189",me="_closeBtn_171mk_227",s={overlay:H,modal:I,summaryGrid:U,summaryCard:z,basicCard:Y,proCard:F,cardTitle:Q,summarySection:V,sectionTitle:X,featureList:J,summary:K,statBasic:Z,statPro:ee,statMixed:te,detailHeader:se,tableWrap:ae,table:ie,toolName:re,description:ce,actionList:ne,none:oe,discountBanner:le,closeBtn:me};function ue({onClose:c}){const{t:e}=j(),{tools:m,summary:n}=L,p=[{title:e("tier.comparison.basic.core","Core MCP workflow"),items:[e("tier.comparison.basic.core.item1","Script create/edit"),e("tier.comparison.basic.core.item2","Instance management"),e("tier.comparison.basic.core.item3","Property control"),e("tier.comparison.basic.core.item4","Selection and search"),e("tier.comparison.basic.core.item5","Tag management"),e("tier.comparison.basic.core.item6","Camera control"),e("tier.comparison.basic.core.item7","Log monitoring")]},{title:e("tier.comparison.basic.sync","Sync (Basic)"),items:[e("tier.comparison.basic.sync.item1","Studio to Local one-way sync"),e("tier.comparison.basic.sync.item2","Manual apply as default")]}],g=[{title:e("tier.comparison.pro.all","Everything in Basic, plus"),items:[]},{title:e("tier.comparison.pro.sync","Advanced Sync workflow"),items:[e("tier.comparison.pro.sync.item1","Per-type sync direction"),e("tier.comparison.pro.sync.item2","Per-type apply mode"),e("tier.comparison.pro.sync.item3","Bidirectional and reverse sync"),e("tier.comparison.pro.sync.item4","Full sync, resync, and push to Studio"),e("tier.comparison.pro.sync.item5","Multi-place sync")]},{title:e("tier.comparison.pro.playtest","Playtest control"),items:[e("tier.comparison.pro.playtest.item1","Play, stop, pause, and resume"),e("tier.comparison.pro.playtest.item2","Playtest state inspection"),e("tier.comparison.pro.playtest.item3","Automated test execution")]},{title:e("tier.comparison.pro.creation","Advanced creation workflow"),items:[e("tier.comparison.pro.creation.item1","Bulk operations"),e("tier.comparison.pro.creation.item2","Terrain generation"),e("tier.comparison.pro.creation.item3","Asset search and insert"),e("tier.comparison.pro.creation.item4","Raycast and spatial analysis"),e("tier.comparison.pro.creation.item5","Environment control")]}];return t.jsx("div",{className:s.overlay,onClick:c,children:t.jsxs("div",{className:s.modal,onClick:a=>a.stopPropagation(),children:[v()&&t.jsx("div",{className:s.discountBanner,children:t.jsx(W,{variant:"centered"})}),t.jsx("h2",{children:e("tier.compare")}),t.jsxs("div",{className:s.summaryGrid,children:[t.jsxs("section",{className:`${s.summaryCard} ${s.basicCard}`,children:[t.jsx("h3",{className:s.cardTitle,children:e("tier.basic")}),p.map(a=>t.jsxs("div",{className:s.summarySection,children:[t.jsx("div",{className:s.sectionTitle,children:a.title}),t.jsx("ul",{className:s.featureList,children:a.items.map(i=>t.jsx("li",{children:i},i))})]},a.title))]}),t.jsxs("section",{className:`${s.summaryCard} ${s.proCard}`,children:[t.jsx("h3",{className:s.cardTitle,children:e("tier.pro")}),g.map(a=>t.jsxs("div",{className:s.summarySection,children:[t.jsx("div",{className:s.sectionTitle,children:a.title}),a.items.length>0&&t.jsx("ul",{className:s.featureList,children:a.items.map(i=>t.jsx("li",{children:i},i))})]},a.title))]})]}),t.jsxs("div",{className:s.summary,children:[t.jsxs("span",{className:s.statBasic,children:["Basic: ",n.totalBasicActions," actions"]}),t.jsxs("span",{className:s.statPro,children:["Pro: ",n.totalProActions," actions"]}),t.jsxs("span",{className:s.statMixed,children:[n.mixedTools," mixed / ",n.proOnlyTools," pro-only"]})]}),t.jsx("div",{className:s.detailHeader,children:e("tier.comparison.detailTitle","Detailed Tool Catalog")}),t.jsx("div",{className:s.tableWrap,children:t.jsxs("table",{className:s.table,children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:e("tools.col.tool")}),t.jsx("th",{children:e("tier.comparison.description","Description")}),t.jsx("th",{children:e("tier.basic")}),t.jsx("th",{children:e("tier.pro")})]})}),t.jsx("tbody",{children:m.map(a=>t.jsxs("tr",{children:[t.jsx("td",{className:s.toolName,children:a.name}),t.jsx("td",{className:s.description,children:e(`tier.tool.${a.name}.desc`,a.description)}),t.jsx("td",{className:s.actionList,children:a.basic.length>0?a.basic.join(", "):t.jsx("span",{className:s.none,children:"—"})}),t.jsx("td",{className:s.actionList,children:a.pro.length>0?a.pro.join(", "):t.jsx("span",{className:s.none,children:"—"})})]},a.name))})]})}),t.jsx("button",{className:s.closeBtn,onClick:c,children:e("tier.comparison.close","Close")})]})})}export{W as D,_e as T,ue as a,pe as u};
@@ -1 +0,0 @@
1
- import{u as x,j as e,n as u,r as p,o as h,m as w,L as m}from"./index-BfvSPSNj.js";const j="_card_1vaoq_2",v="_cardUnread_1vaoq_15",b="_cardRead_1vaoq_20",C="_topRow_1vaoq_25",T="_categoryChip_1vaoq_32",S="_versionChip_1vaoq_45",f="_date_1vaoq_57",k="_title_1vaoq_65",R="_body_1vaoq_74",q="_link_1vaoq_83",H="_newBadge_1vaoq_98",n={card:j,cardUnread:v,cardRead:b,topRow:C,categoryChip:T,versionChip:S,date:f,title:k,body:R,link:q,newBadge:H},E={release:"whatsNew.category.release",notice:"whatsNew.category.notice",deprecation:"whatsNew.category.deprecation",tip:"whatsNew.category.tip"};function y({announcement:s,isNew:d}){const{locale:i,t:c}=x(),o=d?n.cardUnread:n.cardRead,_=s.title[i]??s.title.en,l=s.body[i]??s.body.en,r=s.link?s.link.label[i]??s.link.label.en:null;return e.jsxs("div",{className:`${n.card} ${o}`,children:[e.jsxs("div",{className:n.topRow,children:[e.jsx("span",{className:n.categoryChip,children:c(E[s.category])}),s.version&&e.jsx("span",{className:n.versionChip,children:s.version}),d&&e.jsx("span",{className:n.newBadge,children:c("whatsNew.newBadge","NEW")}),e.jsx("span",{className:n.date,children:s.date})]}),e.jsx("h3",{className:n.title,children:_}),e.jsx("p",{className:n.body,children:l}),s.link&&r&&e.jsxs("a",{className:n.link,href:s.link.url,target:"_blank",rel:"noopener noreferrer",children:["↗"," ",r]})]})}const U="_page_19yl3_2",A="_pageHeader_19yl3_10",B="_pageHeaderText_19yl3_17",I="_pageTitle_19yl3_24",$="_pageSubtitle_19yl3_31",L="_settingsIcon_19yl3_38",M="_section_19yl3_67",W="_sectionTitle_19yl3_73",z="_unreadCount_19yl3_85",O="_empty_19yl3_100",Y="_divider_19yl3_108",t={page:U,pageHeader:A,pageHeaderText:B,pageTitle:I,pageSubtitle:$,settingsIcon:L,section:M,sectionTitle:W,unreadCount:z,empty:O,divider:Y};function K(){const{t:s}=x(),{readSet:d,markRead:i}=u(),c=p.useMemo(()=>{const a=[];for(const N of h)d.has(N.id)||a.push(N.id);return a},[]),o=p.useRef(c);o.current=c,p.useEffect(()=>()=>{o.current.length>0&&i(o.current)},[]);const _=p.useMemo(()=>new Set(c),[c]),l=h.filter(a=>_.has(a.id)),r=l.length>0,g=e.jsxs("div",{className:t.pageHeader,children:[e.jsxs("div",{className:t.pageHeaderText,children:[e.jsx("h1",{className:t.pageTitle,children:s("whatsNew.pageTitle","What's New")}),e.jsx("p",{className:t.pageSubtitle,children:s("whatsNew.pageSubtitle","Stay up to date with MCP changes")})]}),e.jsx(w,{text:s("sidebar.settings","Settings"),children:e.jsx(m,{to:"/settings","aria-label":s("sidebar.settings","Settings"),className:t.settingsIcon,children:"⚙️"})})]});return h.length===0?e.jsxs("div",{className:t.page,children:[g,e.jsx("p",{className:t.empty,children:s("whatsNew.empty","No announcements yet")})]}):e.jsxs("div",{className:t.page,children:[g,r&&e.jsxs("section",{className:t.section,children:[e.jsxs("h2",{className:t.sectionTitle,children:[s("whatsNew.unreadSection","Unread"),e.jsx("span",{className:t.unreadCount,children:l.length})]}),l.map(a=>e.jsx(y,{announcement:a,isNew:!0},`unread-${a.id}`))]}),r&&e.jsx("hr",{className:t.divider}),e.jsxs("section",{className:t.section,children:[e.jsx("h2",{className:t.sectionTitle,children:s("whatsNew.allSection","All Announcements")}),h.map(a=>e.jsx(y,{announcement:a,isNew:_.has(a.id)},`all-${a.id}`))]})]})}export{K as Component};