@weppy/roblox-mcp 2.5.1 → 2.6.1
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/.github/workflows/install-test.yml +55 -4
- package/CHANGELOG.md +27 -0
- package/README.md +29 -46
- package/SUPPORT.md +4 -6
- package/install.ps1 +7 -5
- package/install.sh +4 -2
- package/llms-full.txt +8 -688
- package/llms.txt +3 -13
- 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-kwE4pHZd.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogPage-BFfSWE_s.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{ConfirmModal-DfdyAPrJ.js → ConfirmModal-CeEegyOx.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ConnectionPage-D_mEFudd.css +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ConnectionPage-XuHLuNwR.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/GameChangeDetail-BFTVWFJO.js +6 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{PropertyDiff-Cbx8P1zh.css → GameChangeDetail-Be32PRgR.css} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{InfoLabel-DrK7vhO-.js → InfoLabel-MCIgnb3Z.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/OverviewPage-BrWw_dSf.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{PlaytestPage-CgkzRAqQ.js → PlaytestPage-CxeJXqJZ.js} +2 -2
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SettingsPage-Qd2a2pgi.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{StatusBadge-hJyzgRAl.js → StatusBadge-Dk0M7zQF.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SyncPage-BmMeN4N9.css +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SyncPage-Wu2tD8Lb.js +4 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierComparison-DsesL0R1.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ToolsPage-C7ld3BhY.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TooltipText-CjH5N6RH.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/WhatsNewPage-BwWOghgp.js +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/index-FDX6EnZH.js +355 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/index-XEVy0XAx.css +1 -0
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/{useLiveUptime-BeRNzFBh.js → useLiveUptime-DExWULj9.js} +1 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/index.html +2 -2
- package/plugins/weppy-roblox-mcp/dist/index.js +77 -77
- package/plugins/weppy-roblox-mcp/roblox-plugin/WeppyRobloxMCP.rbxm +0 -0
- package/docs/compatibility.md +0 -44
- package/docs/en/dashboard/changelog.md +0 -114
- package/docs/en/dashboard/connection.md +0 -77
- package/docs/en/dashboard/overview.md +0 -95
- package/docs/en/dashboard/playtest.md +0 -61
- package/docs/en/dashboard/settings.md +0 -60
- package/docs/en/dashboard/sync.md +0 -68
- package/docs/en/dashboard/tools.md +0 -69
- package/docs/en/explorer/overview.md +0 -104
- package/docs/en/installation/README.md +0 -95
- package/docs/en/installation/ai-apps/antigravity.md +0 -89
- package/docs/en/installation/ai-apps/claude-app.md +0 -78
- package/docs/en/installation/ai-apps/claude-code.md +0 -104
- package/docs/en/installation/ai-apps/codex-app.md +0 -56
- package/docs/en/installation/ai-apps/codex-cli.md +0 -67
- package/docs/en/installation/ai-apps/cursor.md +0 -77
- package/docs/en/installation/ai-apps/gemini-cli.md +0 -120
- package/docs/en/installation/roblox-explorer.md +0 -68
- package/docs/en/installation/roblox-plugin.md +0 -96
- package/docs/en/pro-upgrade.md +0 -96
- package/docs/en/sync/luau-lsp.md +0 -41
- package/docs/en/sync/overview.md +0 -153
- package/docs/en/tools/assets-and-effects.md +0 -104
- package/docs/en/tools/instances-and-properties.md +0 -104
- package/docs/en/tools/overview.md +0 -277
- package/docs/en/tools/playtest.md +0 -140
- package/docs/en/tools/scripting.md +0 -66
- package/docs/en/tools/system-and-debugging.md +0 -93
- package/docs/en/tools/world-and-environment.md +0 -102
- package/docs/es/README.md +0 -209
- package/docs/es/dashboard/changelog.md +0 -114
- package/docs/es/dashboard/connection.md +0 -77
- package/docs/es/dashboard/overview.md +0 -95
- package/docs/es/dashboard/playtest.md +0 -61
- package/docs/es/dashboard/settings.md +0 -60
- package/docs/es/dashboard/sync.md +0 -68
- package/docs/es/dashboard/tools.md +0 -69
- package/docs/es/explorer/overview.md +0 -104
- package/docs/es/installation/README.md +0 -87
- package/docs/es/installation/ai-apps/antigravity.md +0 -89
- package/docs/es/installation/ai-apps/claude-app.md +0 -78
- package/docs/es/installation/ai-apps/claude-code.md +0 -104
- package/docs/es/installation/ai-apps/codex-app.md +0 -56
- package/docs/es/installation/ai-apps/codex-cli.md +0 -67
- package/docs/es/installation/ai-apps/cursor.md +0 -77
- package/docs/es/installation/ai-apps/gemini-cli.md +0 -120
- package/docs/es/installation/roblox-explorer.md +0 -58
- package/docs/es/installation/roblox-plugin.md +0 -85
- package/docs/es/pro-upgrade.md +0 -96
- package/docs/es/sync/luau-lsp.md +0 -41
- package/docs/es/sync/overview.md +0 -153
- package/docs/es/tools/assets-and-effects.md +0 -104
- package/docs/es/tools/instances-and-properties.md +0 -104
- package/docs/es/tools/overview.md +0 -277
- package/docs/es/tools/playtest.md +0 -140
- package/docs/es/tools/scripting.md +0 -66
- package/docs/es/tools/system-and-debugging.md +0 -93
- package/docs/es/tools/world-and-environment.md +0 -102
- package/docs/id/README.md +0 -209
- package/docs/id/dashboard/changelog.md +0 -114
- package/docs/id/dashboard/connection.md +0 -77
- package/docs/id/dashboard/overview.md +0 -95
- package/docs/id/dashboard/playtest.md +0 -61
- package/docs/id/dashboard/settings.md +0 -60
- package/docs/id/dashboard/sync.md +0 -68
- package/docs/id/dashboard/tools.md +0 -69
- package/docs/id/explorer/overview.md +0 -104
- package/docs/id/installation/README.md +0 -93
- package/docs/id/installation/ai-apps/antigravity.md +0 -89
- package/docs/id/installation/ai-apps/claude-app.md +0 -78
- package/docs/id/installation/ai-apps/claude-code.md +0 -104
- package/docs/id/installation/ai-apps/codex-app.md +0 -56
- package/docs/id/installation/ai-apps/codex-cli.md +0 -67
- package/docs/id/installation/ai-apps/cursor.md +0 -77
- package/docs/id/installation/ai-apps/gemini-cli.md +0 -120
- package/docs/id/installation/roblox-explorer.md +0 -58
- package/docs/id/installation/roblox-plugin.md +0 -85
- package/docs/id/pro-upgrade.md +0 -96
- package/docs/id/sync/luau-lsp.md +0 -41
- package/docs/id/sync/overview.md +0 -153
- package/docs/id/tools/assets-and-effects.md +0 -104
- package/docs/id/tools/instances-and-properties.md +0 -104
- package/docs/id/tools/overview.md +0 -277
- package/docs/id/tools/playtest.md +0 -140
- package/docs/id/tools/scripting.md +0 -66
- package/docs/id/tools/system-and-debugging.md +0 -93
- package/docs/id/tools/world-and-environment.md +0 -102
- package/docs/installer/assets/index-Bz0amd7x.js +0 -63
- package/docs/installer/assets/index-ei4lRUa6.css +0 -1
- package/docs/installer/index.html +0 -14
- package/docs/installer/manifest.webmanifest +0 -15
- package/docs/installer/sw.js +0 -7
- package/docs/installer/weppy-icon.png +0 -0
- package/docs/ja/README.md +0 -207
- package/docs/ja/dashboard/changelog.md +0 -114
- package/docs/ja/dashboard/connection.md +0 -77
- package/docs/ja/dashboard/overview.md +0 -95
- package/docs/ja/dashboard/playtest.md +0 -61
- package/docs/ja/dashboard/settings.md +0 -60
- package/docs/ja/dashboard/sync.md +0 -68
- package/docs/ja/dashboard/tools.md +0 -69
- package/docs/ja/explorer/overview.md +0 -104
- package/docs/ja/installation/README.md +0 -93
- package/docs/ja/installation/ai-apps/antigravity.md +0 -89
- package/docs/ja/installation/ai-apps/claude-app.md +0 -78
- package/docs/ja/installation/ai-apps/claude-code.md +0 -104
- package/docs/ja/installation/ai-apps/codex-app.md +0 -56
- package/docs/ja/installation/ai-apps/codex-cli.md +0 -67
- package/docs/ja/installation/ai-apps/cursor.md +0 -77
- package/docs/ja/installation/ai-apps/gemini-cli.md +0 -120
- package/docs/ja/installation/roblox-explorer.md +0 -58
- package/docs/ja/installation/roblox-plugin.md +0 -85
- package/docs/ja/pro-upgrade.md +0 -96
- package/docs/ja/sync/luau-lsp.md +0 -41
- package/docs/ja/sync/overview.md +0 -153
- package/docs/ja/tools/assets-and-effects.md +0 -104
- package/docs/ja/tools/instances-and-properties.md +0 -104
- package/docs/ja/tools/overview.md +0 -277
- package/docs/ja/tools/playtest.md +0 -140
- package/docs/ja/tools/scripting.md +0 -66
- package/docs/ja/tools/system-and-debugging.md +0 -93
- package/docs/ja/tools/world-and-environment.md +0 -102
- package/docs/ko/README.md +0 -207
- package/docs/ko/dashboard/changelog.md +0 -114
- package/docs/ko/dashboard/connection.md +0 -77
- package/docs/ko/dashboard/overview.md +0 -95
- package/docs/ko/dashboard/playtest.md +0 -61
- package/docs/ko/dashboard/settings.md +0 -60
- package/docs/ko/dashboard/sync.md +0 -68
- package/docs/ko/dashboard/tools.md +0 -69
- package/docs/ko/explorer/overview.md +0 -104
- package/docs/ko/installation/README.md +0 -95
- package/docs/ko/installation/ai-apps/antigravity.md +0 -88
- package/docs/ko/installation/ai-apps/claude-app.md +0 -78
- package/docs/ko/installation/ai-apps/claude-code.md +0 -104
- package/docs/ko/installation/ai-apps/codex-app.md +0 -56
- package/docs/ko/installation/ai-apps/codex-cli.md +0 -67
- package/docs/ko/installation/ai-apps/cursor.md +0 -77
- package/docs/ko/installation/ai-apps/gemini-cli.md +0 -120
- package/docs/ko/installation/roblox-explorer.md +0 -68
- package/docs/ko/installation/roblox-plugin.md +0 -96
- package/docs/ko/pro-upgrade.md +0 -96
- package/docs/ko/sync/luau-lsp.md +0 -41
- package/docs/ko/sync/overview.md +0 -153
- package/docs/ko/tools/assets-and-effects.md +0 -104
- package/docs/ko/tools/instances-and-properties.md +0 -104
- package/docs/ko/tools/overview.md +0 -277
- package/docs/ko/tools/playtest.md +0 -134
- package/docs/ko/tools/scripting.md +0 -66
- package/docs/ko/tools/system-and-debugging.md +0 -93
- package/docs/ko/tools/world-and-environment.md +0 -102
- package/docs/pt-br/README.md +0 -209
- package/docs/pt-br/dashboard/changelog.md +0 -114
- package/docs/pt-br/dashboard/connection.md +0 -77
- package/docs/pt-br/dashboard/overview.md +0 -95
- package/docs/pt-br/dashboard/playtest.md +0 -61
- package/docs/pt-br/dashboard/settings.md +0 -60
- package/docs/pt-br/dashboard/sync.md +0 -68
- package/docs/pt-br/dashboard/tools.md +0 -69
- package/docs/pt-br/explorer/overview.md +0 -104
- package/docs/pt-br/installation/README.md +0 -93
- package/docs/pt-br/installation/ai-apps/antigravity.md +0 -89
- package/docs/pt-br/installation/ai-apps/claude-app.md +0 -78
- package/docs/pt-br/installation/ai-apps/claude-code.md +0 -104
- package/docs/pt-br/installation/ai-apps/codex-app.md +0 -56
- package/docs/pt-br/installation/ai-apps/codex-cli.md +0 -67
- package/docs/pt-br/installation/ai-apps/cursor.md +0 -77
- package/docs/pt-br/installation/ai-apps/gemini-cli.md +0 -120
- package/docs/pt-br/installation/roblox-explorer.md +0 -58
- package/docs/pt-br/installation/roblox-plugin.md +0 -85
- package/docs/pt-br/pro-upgrade.md +0 -96
- package/docs/pt-br/sync/luau-lsp.md +0 -41
- package/docs/pt-br/sync/overview.md +0 -153
- package/docs/pt-br/tools/assets-and-effects.md +0 -104
- package/docs/pt-br/tools/instances-and-properties.md +0 -104
- package/docs/pt-br/tools/overview.md +0 -277
- package/docs/pt-br/tools/playtest.md +0 -140
- package/docs/pt-br/tools/scripting.md +0 -66
- package/docs/pt-br/tools/system-and-debugging.md +0 -93
- package/docs/pt-br/tools/world-and-environment.md +0 -102
- package/docs/troubleshooting.md +0 -47
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogDetailPage-DRfFUIvC.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ChangelogPage-Dgl8dBt6.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ConnectionPage-9bG71eB1.css +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ConnectionPage-LSvSX1_u.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/OverviewPage-CXsGuoPu.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/PropertyDiff-Dy3MffNh.js +0 -6
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SettingsPage-D2ZBQ2KF.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SyncPage-CLt9jxd8.css +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/SyncPage-eX2Rh-Ct.js +0 -4
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierComparison-BwKqP_4s.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromo-D5n9OoEm.css +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromo.module-CAoUYgIx.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/TierPromoProgress-CLAr1gQq.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/ToolsPage-CqzfCxxH.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/WhatsNewPage-23o8LmsR.js +0 -1
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/index-BfvSPSNj.js +0 -207
- package/plugins/weppy-roblox-mcp/dashboard/dist/assets/index-YfUJSF5s.css +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)
|
package/docs/troubleshooting.md
DELETED
|
@@ -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{r,a as R,u as M,b as B,c as D,j as e,T as m}from"./index-BfvSPSNj.js";import{I as V}from"./InfoLabel-DrK7vhO-.js";import{D as F,P as G}from"./PropertyDiff-Dy3MffNh.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 +0,0 @@
|
|
|
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-BfvSPSNj.js";import{C as G}from"./ConfirmModal-DfdyAPrJ.js";import{u as H,T as Z,D as W,a as q}from"./TierComparison-BwKqP_4s.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 +0,0 @@
|
|
|
1
|
-
._container_1h084_2{max-height:200px;overflow-y:auto;font-family:var(--font-code);font-size:12px;line-height:1.6;padding:8px 12px;background:var(--bg-secondary);border-radius:4px}._entry_1h084_14{display:flex;gap:8px;white-space:nowrap}._timestamp_1h084_21{color:var(--text-muted);flex-shrink:0}._message_1h084_27{color:var(--text-primary);overflow:hidden;text-overflow:ellipsis}._warn_1h084_34 ._message_1h084_27{color:var(--warning)}._error_1h084_39 ._message_1h084_27{color:var(--error)}._empty_1h084_44{color:var(--text-muted);font-style:italic;padding:8px 0}._page_1h5nv_2{display:flex;flex-direction:column;gap:16px;max-width:820px}._card_1h5nv_10{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:16px 20px}._disabled_1h5nv_18{opacity:.4;pointer-events:none}._cardHeader_1h5nv_24{font-family:var(--font-label);font-weight:500;font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-secondary);margin-bottom:12px;display:flex;align-items:center;justify-content:space-between}._clearButton_1h5nv_37{border:1px solid rgba(209,84,84,.5);background:#d154541f;color:#f4c1c1;border-radius:8px;padding:6px 12px;cursor:pointer}._serverGrid_1h5nv_47{display:grid;grid-template-columns:auto 1fr;gap:4px 16px;font-family:var(--font-code);font-size:13px}._serverGrid_1h5nv_47 dt{color:var(--text-muted)}._serverGrid_1h5nv_47 dd{color:var(--text-primary);margin:0}._statusRow_1h5nv_65{display:flex;align-items:center;gap:16px;margin-bottom:12px}._metaItem_1h5nv_72{font-family:var(--font-code);font-size:12px;color:var(--text-secondary)}._table_1h5nv_79{width:100%;border-collapse:collapse;font-family:var(--font-code);font-size:12px}._table_1h5nv_79 th{text-align:left;color:var(--text-muted);font-weight:400;padding:4px 8px 4px 0;border-bottom:1px solid var(--border)}._table_1h5nv_79 td{padding:6px 8px 6px 0;color:var(--text-primary)}._table_1h5nv_79 tr:hover td{background:var(--accent-dim)}._toggleBtn_1h5nv_104{background:none;border:none;color:var(--text-secondary);cursor:pointer;font-size:12px;padding:0 4px;transition:color var(--transition)}._toggleBtn_1h5nv_104:hover{color:var(--accent)}._disconnected_1h5nv_119{text-align:center;padding:32px 16px}._disconnected_1h5nv_119 h3{color:var(--error);font-size:16px;margin:0 0 8px}._disconnected_1h5nv_119 p{color:var(--text-secondary);font-size:13px;margin:0 0 4px}._disconnectedActions_1h5nv_136{display:flex;gap:8px;justify-content:center;margin-top:16px}._btn_1h5nv_143{font-family:var(--font-label);font-size:12px;padding:6px 14px;border-radius:4px;border:1px solid var(--border);background:var(--bg-secondary);color:var(--text-primary);cursor:pointer;transition:background var(--transition),border-color var(--transition)}._btn_1h5nv_143:hover{border-color:var(--accent);background:var(--accent-dim)}._activity_active_1h5nv_161,._activity_stale_1h5nv_162,._activity_unknown_1h5nv_163{display:inline-block;width:7px;height:7px;border-radius:50%;margin-right:6px;vertical-align:middle}._activity_active_1h5nv_161{background:var(--success, #4ade80);box-shadow:0 0 4px var(--success, #4ade80)}._activity_stale_1h5nv_162{background:var(--text-muted, #666)}._activity_unknown_1h5nv_163{background:var(--text-muted, #666);opacity:.4}._killBtn_1h5nv_187{font-family:var(--font-label);font-size:11px;padding:3px 10px;border-radius:4px;border:1px solid rgba(209,84,84,.4);background:#d154541a;color:#e88;cursor:pointer;transition:background var(--transition),border-color var(--transition)}._killBtn_1h5nv_187:hover{background:#d1545440;border-color:#d15454b3;color:#f4c1c1}._emptyRow_1h5nv_206{color:var(--text-muted);font-style:italic}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{u as R,r as i,j as e,d as B,a as w,D as P,i as T,T as D}from"./index-BfvSPSNj.js";import{I as r}from"./InfoLabel-DrK7vhO-.js";import{S as F}from"./StatusBadge-hJyzgRAl.js";import{C as $}from"./ConfirmModal-DfdyAPrJ.js";import{u as H,f as U}from"./useLiveUptime-BeRNzFBh.js";const K="_container_1h084_2",G="_entry_1h084_14",O="_timestamp_1h084_21",V="_message_1h084_27",q="_warn_1h084_34",X="_error_1h084_39",z="_empty_1h084_44",_={container:K,entry:G,timestamp:O,message:V,warn:q,error:X,empty:z};function J(n){const t=new Date(n);return Number.isNaN(t.getTime())?n:`${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`}function Q({entries:n}){const{t}=R(),o=i.useRef(null);return i.useEffect(()=>{const l=o.current;l&&(l.scrollTop=l.scrollHeight)},[n.length]),e.jsx("div",{ref:o,className:_.container,children:n.length===0?e.jsx("div",{className:_.empty,children:t("connection.log.empty","No events yet")}):n.map((l,j)=>e.jsxs("div",{className:`${_.entry} ${l.type?_[l.type]:""}`,children:[e.jsx("span",{className:_.timestamp,children:J(l.timestamp)}),e.jsx("span",{className:_.message,children:l.message})]},j))})}const A=50;function W(){const n=new Date;return`${String(n.getHours()).padStart(2,"0")}:${String(n.getMinutes()).padStart(2,"0")}`}function Y(){const{level:n,status:t,error:o}=B(),[l,j]=i.useState(null),[k,v]=i.useState([]),g=i.useRef(null),u=i.useCallback((a,d)=>{v(x=>{const h=[...x,{timestamp:W(),message:a,type:d}];return h.length>A?h.slice(-A):h})},[]),p=i.useCallback(async()=>{try{const a=await w.get("/connection-info");j(a)}catch{j(null)}},[]),y=i.useCallback(async()=>{try{const a=await w.get("/api/dashboard/connection-log");v(a.entries??[])}catch{v([])}},[]),f=i.useCallback(async()=>{await w.post("/api/dashboard/connection-log/clear"),v([])},[]),S=i.useCallback(async a=>{await w.post("/api/dashboard/kill-agent",{instanceId:a}),await p()},[p]);return i.useEffect(()=>{n!=="disconnected"&&t&&p(),y()},[n,t,p,y]),i.useEffect(()=>{const a=new P;g.current=a,a.connect();const d=a.on("connection",h=>{const m=h,b=m.status==="connected"?"connected":"disconnected";u(`Plugin ${b} — ${m.clientId}`,m.status==="connected"?"info":"warn")}),x=a.on("mcp_status",h=>{const m=h,b=m.status==="registered"?"registered":"unregistered";u(`MCP ${b} — ${m.aiClientName}`,m.status==="registered"?"info":"warn"),p()});return()=>{d(),x(),a.disconnect(),g.current=null}},[u,p]),{status:t,connectionInfo:l,connectionLog:k,level:n,error:o,clearConnectionLog:f,killAgent:S}}const Z="_page_1h5nv_2",ee="_card_1h5nv_10",ne="_disabled_1h5nv_18",te="_cardHeader_1h5nv_24",se="_clearButton_1h5nv_37",ce="_serverGrid_1h5nv_47",oe="_statusRow_1h5nv_65",ie="_metaItem_1h5nv_72",ae="_table_1h5nv_79",le="_toggleBtn_1h5nv_104",re="_disconnected_1h5nv_119",de="_disconnectedActions_1h5nv_136",he="_btn_1h5nv_143",me="_activity_active_1h5nv_161",pe="_activity_stale_1h5nv_162",ge="_activity_unknown_1h5nv_163",ue="_killBtn_1h5nv_187",xe="_emptyRow_1h5nv_206",s={page:Z,card:ee,disabled:ne,cardHeader:te,clearButton:se,serverGrid:ce,statusRow:oe,metaItem:ie,table:ae,toggleBtn:le,disconnected:re,disconnectedActions:de,btn:he,activity_active:me,activity_stale:pe,activity_unknown:ge,killBtn:ue,emptyRow:xe};function N(n,t){const o=Math.max(0,Math.floor((Date.now()-n)/1e3));return o<60?`${o}${t("connection.time.secondsAgo","s ago")}`:o<3600?`${Math.floor(o/60)}${t("connection.time.minutesAgo","m ago")}`:`${Math.floor(o/3600)}${t("connection.time.hoursAgo","h ago")}`}function je(n){return n?Date.now()-n<3e4?"active":"stale":"unknown"}function ye(){var I;const{t:n}=R(),{status:t,connectionInfo:o,connectionLog:l,level:j,clearConnectionLog:k,killAgent:v}=Y(),{show:g}=T(),[u,p]=i.useState(!0),[y,f]=i.useState(!1),[S,a]=i.useState(!1),[d,x]=i.useState(null),[h,m]=i.useState(!1),b=H(t==null?void 0:t.uptime),C=j==="disconnected",L=C?"offline":"online",M=async()=>{if(d){m(!0);try{await v(d.instanceId),g(n("connection.agents.killed","Agent killed"),"success"),x(null)}catch{g(n("connection.agents.killFailed","Failed to kill agent"),"error")}finally{m(!1)}}},E=async()=>{a(!0);try{await k(),g(n("toast.clearSuccess","Cleared successfully"),"success"),f(!1)}catch{g(n("toast.clearFailed","Failed to clear data"),"error")}finally{a(!1)}};return e.jsxs("div",{className:s.page,children:[e.jsxs("div",{className:s.card,children:[e.jsx("div",{className:s.cardHeader,children:n("connection.server.title","Server Status")}),C?e.jsxs("div",{className:s.disconnected,children:[e.jsx("h3",{children:n("level.l0.title")}),e.jsx("p",{children:n("level.l0.message")}),e.jsx("p",{children:n("common.reconnecting")}),e.jsxs("div",{className:s.disconnectedActions,children:[e.jsx("button",{className:s.btn,onClick:()=>window.location.reload(),children:n("connection.reconnect","Reconnect")}),e.jsx("button",{className:s.btn,onClick:()=>{window.location.hash="#/settings"},children:n("connection.checkSettings","Check Settings")})]})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:s.statusRow,children:e.jsx(F,{status:L})}),e.jsxs("dl",{className:s.serverGrid,children:[(t==null?void 0:t.version)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(r,{label:n("connection.server.version","Version"),tooltip:n("connection.server.version.tooltip","Installed MCP server version")})}),e.jsx("dd",{children:e.jsx(D,{text:n("connection.server.version.tooltip","Installed MCP server version"),children:`v${t.version}`})})]}),(t==null?void 0:t.pid)!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(r,{label:n("connection.server.pid","PID"),tooltip:n("connection.server.pid.tooltip","Operating system process identifier")})}),e.jsx("dd",{children:t.pid})]}),(t==null?void 0:t.uptime)!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(r,{label:n("connection.server.uptime","Uptime"),tooltip:n("connection.server.uptime.tooltip","Time elapsed since the MCP server started")})}),e.jsx("dd",{children:U(b??t.uptime)})]}),(t==null?void 0:t.sessionId)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(r,{label:n("connection.server.session","Session"),tooltip:n("connection.server.session.tooltip","Current MCP session identifier")})}),e.jsx("dd",{children:t.sessionId.slice(0,8)})]}),(o==null?void 0:o.serverExecutable)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:e.jsx(r,{label:n("connection.server.exec","Exec"),tooltip:n("connection.server.exec.tooltip","Executable path used to launch the MCP server")})}),e.jsx("dd",{children:o.serverExecutable})]})]})]})]}),e.jsxs("div",{className:`${s.card} ${C?s.disabled:""}`,children:[e.jsxs("div",{className:s.cardHeader,children:[e.jsxs("span",{children:[n("connection.agents.title","AI Agents")," ","(",(o==null?void 0:o.mcpInstanceCount)??0,")"]}),e.jsx("button",{className:s.toggleBtn,onClick:()=>p(c=>!c),"aria-label":u?n("common.collapse","Collapse"):n("common.expand","Expand"),children:u?"▾":"▸"})]}),u&&e.jsxs("table",{className:s.table,children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:n("connection.agents.name","Agent")}),e.jsx("th",{children:e.jsx(r,{label:n("connection.server.pid","PID"),tooltip:n("connection.server.pid.tooltip","Operating system process identifier")})}),e.jsx("th",{children:e.jsx(r,{label:n("connection.agents.projectRoot","Project Root"),tooltip:n("connection.agents.projectRoot.tooltip","Authoritative project root for sync ownership")})}),e.jsx("th",{children:n("connection.agents.connected","Connected")}),e.jsx("th",{children:e.jsx(r,{label:n("connection.agents.lastSeen","Last Seen"),tooltip:n("connection.agents.lastSeen.tooltip","Most recent heartbeat or activity from this agent")})}),e.jsx("th",{children:e.jsx(r,{label:n("connection.agents.lastCommand","Last Command"),tooltip:n("connection.agents.lastCommand.tooltip","Most recent tool call executed by this agent")})}),e.jsx("th",{})]})}),e.jsx("tbody",{children:o!=null&&o.mcpInstances&&o.mcpInstances.length>0?o.mcpInstances.map(c=>e.jsxs("tr",{children:[e.jsxs("td",{children:[e.jsx("span",{className:s[`activity_${je(c.lastSeen)}`]}),c.aiClientName??n("connection.agents.unknown","Unknown")]}),e.jsx("td",{children:c.pid}),e.jsx("td",{children:c.projectRoot??c.cwd??n("connection.agents.projectRoot.unresolved","Unresolved")}),e.jsx("td",{children:N(c.connectedAt,n)}),e.jsx("td",{children:c.lastSeen?N(c.lastSeen,n):"-"}),e.jsx("td",{children:c.lastCommandAt?N(c.lastCommandAt,n):"-"}),e.jsx("td",{children:!c.isServer&&e.jsx("button",{className:s.killBtn,onClick:()=>x({instanceId:c.instanceId,name:c.aiClientName??c.instanceId.slice(0,8)}),children:n("connection.agents.kill","Kill")})})]},c.instanceId)):e.jsx("tr",{children:e.jsx("td",{colSpan:7,className:s.emptyRow,children:n("connection.agents.none","No agents connected")})})})]})]}),e.jsxs("div",{className:`${s.card} ${C?s.disabled:""}`,children:[e.jsxs("div",{className:s.cardHeader,children:[n("connection.plugins.title","Plugins")," ","(",((I=t==null?void 0:t.pluginClients)==null?void 0:I.length)??0,")"]}),e.jsxs("table",{className:s.table,children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:n("connection.plugins.place","Place")}),e.jsx("th",{children:e.jsx(r,{label:n("connection.plugins.clientId","Client ID"),tooltip:n("connection.plugins.clientId.tooltip","Unique plugin client identifier for this Studio connection")})}),e.jsx("th",{children:e.jsx(r,{label:n("connection.plugins.lastSeen","Last Seen"),tooltip:n("connection.plugins.lastSeen.tooltip","Most recent heartbeat received from the plugin")})}),e.jsx("th",{children:e.jsx(r,{label:n("connection.plugins.version","Ver"),tooltip:n("connection.plugins.version.tooltip","Installed plugin version reported by Studio")})})]})}),e.jsx("tbody",{children:t!=null&&t.pluginClients&&t.pluginClients.length>0?t.pluginClients.map(c=>e.jsxs("tr",{children:[e.jsx("td",{children:c.placeName??c.projectName??"-"}),e.jsx("td",{children:c.clientId.slice(0,10)}),e.jsx("td",{children:N(c.lastSeen,n)}),e.jsx("td",{children:c.pluginVersion??"-"})]},c.clientId)):e.jsx("tr",{children:e.jsx("td",{colSpan:4,className:s.emptyRow,children:n("connection.plugins.none","No plugins connected")})})})]})]}),e.jsxs("div",{className:`${s.card} ${C?s.disabled:""}`,children:[e.jsxs("div",{className:s.cardHeader,children:[e.jsx("span",{children:n("connection.log.title","Connection Log")}),e.jsx("button",{className:s.clearButton,onClick:()=>f(!0),children:n("common.clear","Clear")})]}),e.jsx(Q,{entries:l})]}),e.jsx($,{open:y,title:n("connection.clear.title","Clear connection log?"),message:n("connection.clear.message","This permanently removes the stored connection log for the current project."),cancelLabel:n("common.cancel","Cancel"),confirmLabel:n("common.clear","Clear"),loading:S,onCancel:()=>!S&&f(!1),onConfirm:E}),e.jsx($,{open:!!d,title:n("connection.agents.kill.title","Kill agent?"),message:`"${d==null?void 0:d.name}" 프로세스를 강제 종료합니다. 해당 에이전트의 진행 중인 작업이 중단됩니다.`,cancelLabel:n("common.cancel","Cancel"),confirmLabel:n("connection.agents.kill","Kill"),loading:h,onCancel:()=>!h&&x(null),onConfirm:M})]})}export{ye as Component};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{j as t,u as $,r as u,d as L,a as D,D as F,T as U}from"./index-BfvSPSNj.js";import{I as V}from"./InfoLabel-DrK7vhO-.js";import{S as A}from"./StatusBadge-hJyzgRAl.js";import{D as z,P as O}from"./PropertyDiff-Dy3MffNh.js";import{u as J,T as X}from"./TierComparison-BwKqP_4s.js";import{u as q,f as K}from"./useLiveUptime-BeRNzFBh.js";import{T as Q}from"./TierPromoProgress-CLAr1gQq.js";import"./TierPromo.module-CAoUYgIx.js";const W="_page_1xgxh_2",Y="_card_1xgxh_10",Z="_cardHeader_1xgxh_17",ee="_disconnectCard_1xgxh_28",te="_disconnectIcon_1xgxh_36",se="_disconnectTitle_1xgxh_41",ne="_disconnectMessage_1xgxh_48",ie="_reconnectGuide_1xgxh_55",re="_guideStep_1xgxh_64",ce="_stepNumber_1xgxh_72",ae="_reconnectIndicator_1xgxh_88",oe="_reconnectDot_1xgxh_98",le="_pulse_1xgxh_1",de="_disconnectActions_1xgxh_112",me="_btn_1xgxh_118",xe="_btnSecondary_1xgxh_134",ge="_metricRow_1xgxh_152",he="_metricGrid_1xgxh_158",ue="_metricCard_1xgxh_164",ve="_metric_ok_1xgxh_174",_e="_metric_warn_1xgxh_179",pe="_metric_error_1xgxh_184",fe="_metricHeader_1xgxh_189",Ce="_metricIcon_1xgxh_200",je="_metricTitle_1xgxh_204",we="_metricValue_1xgxh_208",Ne="_metricSubtitle_1xgxh_215",ye="_guideCard_1xgxh_225",Te="_guideTitle_1xgxh_232",Se="_checklist_1xgxh_239",be="_feedEmpty_1xgxh_263",Ie="_feedList_1xgxh_270",ke="_feedItem_1xgxh_278",De="_feedTime_1xgxh_291",Me="_feedIcon_1xgxh_298",Pe="_feedSummary_1xgxh_304",Ee="_feedText_1xgxh_313",Be="_feedContext_1xgxh_321",He="_feedItemClickable_1xgxh_330",Re="_feedChevron_1xgxh_338",$e="_feedDetail_1xgxh_347",Ge="_feedDetailPre_1xgxh_356",Le="_feedDetailText_1xgxh_365",Fe="_changelogSummary_1xgxh_372",Ue="_changeTag_1xgxh_381",Ve="_tierBar_1xgxh_393",Ae="_tierBarTrack_1xgxh_399",ze="_tierBarFillBasic_1xgxh_407",Oe="_tierBarFillPro_1xgxh_412",Je="_tierLabels_1xgxh_417",s={page:W,card:Y,cardHeader:Z,disconnectCard:ee,disconnectIcon:te,disconnectTitle:se,disconnectMessage:ne,reconnectGuide:ie,guideStep:re,stepNumber:ce,reconnectIndicator:ae,reconnectDot:oe,pulse:le,disconnectActions:de,btn:me,btnSecondary:xe,metricRow:ge,metricGrid:he,metricCard:ue,metric_ok:ve,metric_warn:_e,metric_error:pe,metricHeader:fe,metricIcon:Ce,metricTitle:je,metricValue:we,metricSubtitle:Ne,guideCard:ye,guideTitle:Te,checklist:Se,feedEmpty:be,feedList:Ie,feedItem:ke,feedTime:De,feedIcon:Me,feedSummary:Pe,feedText:Ee,feedContext:Be,feedItemClickable:He,feedChevron:Re,feedDetail:$e,feedDetailPre:Ge,feedDetailText:Le,changelogSummary:Fe,changeTag:Ue,tierBar:Ve,tierBarTrack:Ae,tierBarFillBasic:ze,tierBarFillPro:Oe,tierLabels:Je};function N({title:e,value:i,icon:r,subtitle:c,status:a,children:n}){const d=a?s[`metric_${a}`]:"";return t.jsxs("div",{className:`${s.metricCard} ${d}`,children:[t.jsxs("div",{className:s.metricHeader,children:[r&&t.jsx("span",{className:s.metricIcon,children:r}),t.jsx("span",{className:s.metricTitle,children:e})]}),t.jsx("div",{className:s.metricValue,children:i}),c&&t.jsx("div",{className:s.metricSubtitle,children:c}),n]})}function Xe(e){var r,c;const i=e==null?void 0:e.contextSummary;return(i==null?void 0:i.intent)??((c=(r=i==null?void 0:i.affectedAreas)==null?void 0:r[0])==null?void 0:c.label)??(i==null?void 0:i.testScenario)??null}function E({changes:e}){const{t:i}=$(),[r,c]=u.useState(null);return e.length===0?t.jsx("div",{className:s.feedEmpty,children:i("overview.feed.empty")}):t.jsx("div",{className:s.feedList,children:e.map((a,n)=>{const d=r===n,o=a.raw,v=o&&(o.before!=null||o.after!=null||o.details!=null),_=Xe(o);return t.jsxs("div",{children:[t.jsxs("div",{className:`${s.feedItem} ${v?s.feedItemClickable:""}`,onClick:()=>v&&c(d?null:n),children:[t.jsx("span",{className:s.feedTime,children:a.timestamp}),t.jsx("span",{className:s.feedIcon,children:a.icon}),t.jsxs("span",{className:s.feedText,children:[t.jsx("span",{className:s.feedSummary,children:a.summary}),_&&t.jsx("span",{className:s.feedContext,children:_})]}),v&&t.jsx("span",{className:s.feedChevron,children:d?"▴":"▾"})]}),d&&o&&t.jsx("div",{className:s.feedDetail,children:t.jsx(qe,{change:o})})]},n)})})}function qe({change:e}){return e.category==="script"&&(e.before||e.after)?t.jsx(z,{before:e.before,after:e.after}):e.category==="property"?t.jsx(O,{before:e.before,after:e.after}):e.details?t.jsx("pre",{className:s.feedDetailPre,children:JSON.stringify(e.details,null,2)}):t.jsx("div",{className:s.feedDetailText,children:e.target})}const B=20;function G(e){return`${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`}function H(){return G(new Date)}function R(e){switch(e){case"script":return"📝";case"instance":return"🧱";case"property":return"🎨";case"lighting":return"💡";case"terrain":return"⛰️";case"asset":return"📦";default:return"🔧"}}function Ke(){const{level:e,status:i}=L(),r=J(),[c,a]=u.useState(null),[n,d]=u.useState(null),[o,v]=u.useState(null),[_,g]=u.useState([]),y=u.useRef(null),T=u.useCallback(async()=>{try{const l=await D.get("/connection-info");a(l)}catch{a(null)}},[]),S=u.useCallback(async()=>{try{const l=await D.get("/api/dashboard/changelog/active");if(v(l),l.recentChanges&&l.recentChanges.length>0){const p=l.recentChanges.map(h=>({timestamp:h.timestamp?G(new Date(h.timestamp)):H(),icon:R(h.category),summary:h.summary,category:h.category,raw:h}));g(p)}}catch{v(null)}},[]),f=u.useCallback(async()=>{try{const l=await D.get("/sync/status");d(l)}catch{d(null)}},[]);return u.useEffect(()=>{e!=="disconnected"?(T(),S(),f()):(a(null),d(null),v(null));const l=new F;y.current=l,l.connect();const p=l.on("game_change",C=>{const m=C,j={timestamp:H(),icon:R(m.category),summary:m.summary,category:m.category};g(k=>{const w=[j,...k];return w.length>B?w.slice(0,B):w}),S()}),h=l.on("sync",C=>{const m=C;d(j=>({...j,state:m.status,...m.placeId?{placeId:m.placeId}:{}}))});return()=>{p(),h(),l.disconnect(),y.current=null}},[e,T,S,f]),{level:e,status:i,connectionInfo:c,syncStatus:n,changeSummary:o,recentChanges:_,tier:r}}function M(e){return e.scriptsModified+e.scriptsCreated+e.instancesCreated+e.instancesDeleted+e.instancesMoved+e.propertiesChanged+e.assetsInserted+(e.lightingChanged?1:0)+(e.terrainChanged?1:0)}function Qe(e,i){switch(e){case"syncing":return i("status.syncing","Syncing");case"initializing":return i("status.initializing","Initializing");case"error":return i("status.error","Error");default:return i("status.idle","Idle")}}function We(e){switch(e){case"syncing":return"ok";case"initializing":return"warn";case"error":return"error";default:return"ok"}}function I(e,i,r,c){return t.jsxs("div",{className:e.metricSubtitle,children:[t.jsx(V,{label:i,tooltip:r}),": ",c]},i)}function x(e,i){return t.jsx(U,{text:i,children:e})}function ct(){var w,P;const{t:e}=$(),{level:i,status:r,connectionInfo:c,syncStatus:a,changeSummary:n,recentChanges:d,tier:o}=Ke(),v=q(r==null?void 0:r.uptime);if(i==="disconnected")return t.jsx("div",{className:s.page,children:t.jsxs("div",{className:s.disconnectCard,children:[t.jsx("div",{className:s.disconnectIcon,children:"⚠️"}),t.jsx("h2",{className:s.disconnectTitle,children:e("overview.l0.title")}),t.jsx("p",{className:s.disconnectMessage,children:e("overview.l0.message")}),t.jsxs("div",{className:s.reconnectGuide,children:[t.jsxs("div",{className:s.guideStep,children:[t.jsx("span",{className:s.stepNumber,children:"1"}),t.jsx("span",{children:e("overview.l0.step1")})]}),t.jsxs("div",{className:s.guideStep,children:[t.jsx("span",{className:s.stepNumber,children:"2"}),t.jsx("span",{children:e("overview.l0.step2")})]})]}),t.jsxs("div",{className:s.reconnectIndicator,children:[t.jsx("span",{className:s.reconnectDot}),e("overview.l0.reconnecting")]}),t.jsxs("div",{className:s.disconnectActions,children:[t.jsx("button",{className:s.btn,onClick:()=>window.location.reload(),children:e("overview.l0.reconnectBtn")}),t.jsx("button",{className:s.btnSecondary,onClick:()=>{window.location.hash="#/settings"},children:e("overview.l0.settingsBtn")})]})]})});const _=(c==null?void 0:c.mcpInstanceCount)??0,g=((w=c==null?void 0:c.mcpInstances)==null?void 0:w.find(b=>!b.isServer&&b.aiClientName))??((P=c==null?void 0:c.mcpInstances)==null?void 0:P.find(b=>!!b.aiClientName))??null,y=(r==null?void 0:r.pluginClients)??[],T=y.length>0,S=(r==null?void 0:r.sessionId)??(c==null?void 0:c.sessionId)??"-",f=e("overview.metric.server.tooltip","MCP server runtime and process status"),l=e("overview.metric.plugin.tooltip","Roblox Studio plugin connection and version status"),p=e("overview.metric.agent.tooltip","Connected AI coding agents and their runtime state"),h=e("overview.metric.sync.tooltip","Current Studio to local sync activity"),C=r?[I(s,e("overview.meta.version","Version"),e("overview.meta.version.tooltip","Installed MCP server version"),`v${r.version}`),I(s,e("overview.meta.session","Session"),e("overview.meta.session.tooltip","Current MCP session identifier"),S),I(s,e("overview.meta.pid","PID"),e("overview.meta.pid.tooltip","Operating system process identifier"),String(r.pid??"-")),I(s,e("overview.meta.uptime","Uptime"),e("overview.meta.uptime.tooltip","Time elapsed since the MCP server started"),K(v??r.uptime))]:[];if(i==="serverOnly")return t.jsxs("div",{className:s.page,children:[t.jsxs("div",{className:s.metricRow,children:[t.jsx(N,{title:x(e("overview.metric.server"),f),value:x(e("status.online"),f),icon:"🖥️",status:"ok",children:t.jsxs(t.Fragment,{children:[C,t.jsx(A,{status:"online"})]})}),t.jsx(N,{title:x(e("overview.metric.agent"),p),value:x((g==null?void 0:g.aiClientName)??e("overview.metric.noAgent"),p),icon:"🤖",subtitle:_>1?`${_} ${e("overview.metric.agent.instancesUnit","instances")}`:void 0,status:g?"ok":"warn"})]}),t.jsxs("div",{className:s.guideCard,children:[t.jsx("h3",{className:s.guideTitle,children:e("overview.l1.pluginGuide")}),t.jsxs("ul",{className:s.checklist,children:[t.jsx("li",{children:e("overview.l1.check1")}),t.jsx("li",{children:e("overview.l1.check2")})]})]}),t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.feed.title")}),d.length>0?t.jsx(E,{changes:d}):t.jsx("div",{className:s.feedEmpty,children:e("overview.l1.feedHint")})]}),n&&M(n)>0&&t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.changelog.title")}),t.jsxs("div",{className:s.changelogSummary,children:[t.jsxs("span",{children:[e("overview.changelog.entries","Entries"),": ",M(n)]}),n.scriptsModified>0&&t.jsxs("span",{className:s.changeTag,children:["📝"," ",n.scriptsModified," ",e("overview.changelog.scripts")]}),n.instancesCreated>0&&t.jsxs("span",{className:s.changeTag,children:["🧱"," ",n.instancesCreated," ",e("overview.changelog.instances")]}),n.propertiesChanged>0&&t.jsxs("span",{className:s.changeTag,children:["🎨"," ",n.propertiesChanged," ",e("overview.changelog.properties")]}),n.assetsInserted>0&&t.jsxs("span",{className:s.changeTag,children:["📦"," ",n.assetsInserted," ",e("overview.changelog.assets")]})]})]})]});const m=y[0],j=n?M(n):0,k=!!n&&j>0;return t.jsxs("div",{className:s.page,children:[t.jsxs("div",{className:s.metricGrid,children:[t.jsx(N,{title:x(e("overview.metric.server"),f),value:x(e("status.online"),f),icon:"🖥️",status:"ok",children:t.jsx(t.Fragment,{children:C})}),t.jsx(N,{title:x(e("overview.metric.plugin"),l),value:x(e(T?"status.online":"status.offline"),l),icon:"🔌",subtitle:m?`${m.placeName??m.projectName??"-"} / v${m.pluginVersion??"-"}`:void 0,status:T?"ok":"error"}),t.jsx(N,{title:x(e("overview.metric.agent"),p),value:x((g==null?void 0:g.aiClientName)??e("overview.metric.noAgent"),p),icon:"🤖",subtitle:_>1?`${_} ${e("overview.metric.agent.instancesUnit","instances")}`:void 0,status:g?"ok":"warn"}),t.jsx(N,{title:x(e("overview.metric.sync"),h),value:x(Qe(a==null?void 0:a.state,e),h),icon:"🔄",status:We(a==null?void 0:a.state)})]}),t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.feed.title")}),t.jsx(E,{changes:d})]}),k&&t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.changelog.title")}),t.jsxs("div",{className:s.changelogSummary,children:[t.jsxs("span",{children:[e("overview.changelog.entries","Entries"),": ",j]}),n.scriptsModified>0&&t.jsxs("span",{className:s.changeTag,children:["📝"," ",n.scriptsModified," ",e("overview.changelog.scripts")]}),n.instancesCreated>0&&t.jsxs("span",{className:s.changeTag,children:["🧱"," ",n.instancesCreated," ",e("overview.changelog.instances")]}),n.propertiesChanged>0&&t.jsxs("span",{className:s.changeTag,children:["🎨"," ",n.propertiesChanged," ",e("overview.changelog.properties")]}),n.assetsInserted>0&&t.jsxs("span",{className:s.changeTag,children:["📦"," ",n.assetsInserted," ",e("overview.changelog.assets")]})]})]}),!o.loading&&o.tier==="basic"&&o.totalCalls>0&&t.jsxs("div",{className:s.card,children:[t.jsx("div",{className:s.cardHeader,children:e("overview.tier.title")}),t.jsx(Q,{basicCalls:o.basicCalls,proCalls:o.proCalls,totalCalls:o.totalCalls,proUsagePercent:o.proUsagePercent,upgradeHref:X.overview})]})]})}export{ct as Component};
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import{u as p,r as _,j as n}from"./index-BfvSPSNj.js";const N="_container_uv8oc_2",x="_header_uv8oc_10",v="_modeBtn_uv8oc_18",j="_modeBtnActive_uv8oc_33",y="_unifiedView_uv8oc_40",g="_diffLine_uv8oc_46",C="_lineNum_uv8oc_55",B="_lineContent_uv8oc_64",V="_lineAdded_uv8oc_68",w="_lineRemoved_uv8oc_73",L="_lineContext_uv8oc_78",$="_sideBySide_uv8oc_83",b="_sidePane_uv8oc_90",A="_sideLabel_uv8oc_100",S="_sideContent_uv8oc_112",P="_empty_uv8oc_117",e={container:N,header:x,modeBtn:v,modeBtnActive:j,unifiedView:y,diffLine:g,lineNum:C,lineContent:B,lineAdded:V,lineRemoved:w,lineContext:L,sideBySide:$,sidePane:b,sideLabel:A,sideContent:S,empty:P};function R(i,a){const t=i.split(`
|
|
2
|
-
`),d=a.split(`
|
|
3
|
-
`),o=[],u=Math.max(t.length,d.length);let s=0,l=0;for(;(s<t.length||l<d.length)&&(s<t.length&&l<d.length?t[s]===d[l]?(o.push({type:"context",content:t[s],lineNum:l+1}),s++,l++):(o.push({type:"removed",content:t[s],lineNum:s+1}),s++,s<t.length&&t[s]===d[l]?(o.push({type:"added",content:d[l],lineNum:l+1}),l++):l<d.length&&(o.push({type:"added",content:d[l],lineNum:l+1}),l++)):s<t.length?(o.push({type:"removed",content:t[s],lineNum:s+1}),s++):l<d.length&&(o.push({type:"added",content:d[l],lineNum:l+1}),l++),!(o.length>u*3)););return o}function E({before:i,after:a}){const{t}=p(),[d,o]=_.useState("unified"),u=typeof i=="string"?i:i!=null?JSON.stringify(i,null,2):"",s=typeof a=="string"?a:a!=null?JSON.stringify(a,null,2):"",l=_.useMemo(()=>R(u,s),[u,s]);if(!u&&!s)return n.jsx("div",{className:e.container,children:n.jsx("div",{className:e.empty,children:t("changelog.diff.empty","No diff available")})});if(!u&&s){const c=s.split(`
|
|
4
|
-
`);return n.jsx("div",{className:e.container,children:n.jsx("div",{className:e.unifiedView,children:c.map((r,h)=>n.jsxs("div",{className:`${e.diffLine} ${e.lineAdded}`,children:[n.jsx("span",{className:e.lineNum,children:h+1}),n.jsxs("span",{className:e.lineContent,children:["+ ",r]})]},h))})})}return n.jsxs("div",{className:e.container,children:[n.jsxs("div",{className:e.header,children:[n.jsx("button",{className:`${e.modeBtn} ${d==="unified"?e.modeBtnActive:""}`,onClick:()=>o("unified"),children:t("changelog.diff.unified","Unified")}),n.jsx("button",{className:`${e.modeBtn} ${d==="side-by-side"?e.modeBtnActive:""}`,onClick:()=>o("side-by-side"),children:t("changelog.diff.sideBySide","Side by Side")})]}),d==="unified"?n.jsx("div",{className:e.unifiedView,children:l.map((c,r)=>n.jsxs("div",{className:`${e.diffLine} ${c.type==="added"?e.lineAdded:c.type==="removed"?e.lineRemoved:e.lineContext}`,children:[n.jsx("span",{className:e.lineNum,children:c.lineNum??""}),n.jsxs("span",{className:e.lineContent,children:[c.type==="added"?"+ ":c.type==="removed"?"- ":" ",c.content]})]},r))}):n.jsxs("div",{className:e.sideBySide,children:[n.jsxs("div",{className:e.sidePane,children:[n.jsx("div",{className:e.sideLabel,children:t("changelog.diff.before","Before")}),n.jsx("div",{className:e.sideContent,children:u.split(`
|
|
5
|
-
`).map((c,r)=>n.jsxs("div",{className:`${e.diffLine} ${e.lineContext}`,children:[n.jsx("span",{className:e.lineNum,children:r+1}),n.jsx("span",{className:e.lineContent,children:c})]},r))})]}),n.jsxs("div",{className:e.sidePane,children:[n.jsx("div",{className:e.sideLabel,children:t("changelog.diff.after","After")}),n.jsx("div",{className:e.sideContent,children:s.split(`
|
|
6
|
-
`).map((c,r)=>n.jsxs("div",{className:`${e.diffLine} ${e.lineContext}`,children:[n.jsx("span",{className:e.lineNum,children:r+1}),n.jsx("span",{className:e.lineContent,children:c})]},r))})]})]})]})}const D="_container_8lpbs_2",k="_oldValue_8lpbs_11",J="_arrow_8lpbs_17",M="_newValue_8lpbs_22",m={container:D,oldValue:k,arrow:J,newValue:M};function f(i){return i==null?"nil":typeof i=="string"?`"${i}"`:typeof i=="object"?JSON.stringify(i):String(i)}function U({before:i,after:a}){const t=i!=null,d=a!=null;return!t&&!d?null:t?d?n.jsxs("div",{className:m.container,children:[n.jsx("span",{className:m.oldValue,children:f(i)}),n.jsx("span",{className:m.arrow,children:"→"}),n.jsx("span",{className:m.newValue,children:f(a)})]}):n.jsx("div",{className:m.container,children:n.jsx("span",{className:m.oldValue,children:f(i)})}):n.jsx("div",{className:m.container,children:n.jsx("span",{className:m.newValue,children:f(a)})})}export{E as D,U as P};
|