sagadeck 1.7.1 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -4
- package/SKILL.md +10 -3
- package/bin/sagadeck.js +23 -0
- package/docs/ANDAMENTO.md +483 -1
- package/docs/PLANO-MELHORIAS.md +180 -0
- package/docs/REFERENCIA.md +184 -105
- package/package.json +34 -2
- package/src/ai/commands.js +2 -2
- package/src/ai/deck-ai.js +14 -5
- package/src/ai/ia-check.js +127 -0
- package/src/ai/ia-config.js +2 -2
- package/src/ai/llm.js +5 -1
- package/src/ai/map-analysis-run.js +119 -0
- package/src/ai/map-data.js +221 -0
- package/src/ai/quality.js +1 -1
- package/src/ai/video-generation.js +70 -25
- package/src/build.js +51 -15
- package/src/elements.js +39 -1
- package/src/export/browser.js +23 -1
- package/src/export/pptx.js +9 -3
- package/src/export/shots.js +10 -3
- package/src/fiscal/normalize.js +19 -0
- package/src/fs-retry.js +37 -2
- package/src/import/office.js +5 -4
- package/src/layouts.js +114 -99
- package/src/lessons.js +1 -1
- package/src/library.js +7 -7
- package/src/map-analysis.js +109 -0
- package/src/map-config.js +89 -0
- package/src/map-routing.js +82 -0
- package/src/map-services.js +60 -0
- package/src/map.js +274 -0
- package/src/mcp/server.js +17 -0
- package/src/motion.js +20 -6
- package/src/purpose.js +1 -1
- package/src/runtime/base.css +105 -329
- package/src/runtime/fit.js +3 -2
- package/src/runtime/fonts/amatic-sc.css +3 -0
- package/src/runtime/fonts/bebas-neue.css +2 -0
- package/src/runtime/fonts/cabin-sketch.css +2 -0
- package/src/runtime/fonts/fraunces.css +3 -0
- package/src/runtime/fonts/gelasio.css +3 -0
- package/src/runtime/fonts/ibm-plex-mono.css +4 -0
- package/src/runtime/fonts/index.json +10 -1
- package/src/runtime/fonts/itim.css +2 -0
- package/src/runtime/fonts/montserrat.css +2 -0
- package/src/runtime/fonts/space-grotesk.css +2 -0
- package/src/runtime/map-background.js +91 -0
- package/src/runtime/map.js +266 -0
- package/src/runtime/runtime.js +81 -100
- package/src/runtime/skins/caderno.css +33 -0
- package/src/runtime/skins/cartaz.css +27 -0
- package/src/runtime/skins/infografico.css +29 -0
- package/src/runtime/skins/lousa.css +22 -0
- package/src/runtime/skins/musgo.css +42 -0
- package/src/runtime/vendor/LEAFLET-LICENSE.txt +26 -0
- package/src/runtime/vendor/MAPLIBRE-LEAFLET-LICENSE.txt +15 -0
- package/src/runtime/vendor/MAPLIBRE-LICENSE.txt +116 -0
- package/src/runtime/vendor/geo-contornos.json +1 -0
- package/src/runtime/vendor/leaflet.css +661 -0
- package/src/runtime/vendor/leaflet.js +6 -0
- package/src/runtime/vendor/maplibre-gl.css +1 -0
- package/src/runtime/vendor/maplibre-gl.js +825 -0
- package/src/runtime/vendor/maplibre-leaflet.js +234 -0
- package/src/runtime/vendor/maplibre-worker.js +10 -0
- package/src/studio/ai-chat-route.js +20 -0
- package/src/studio/assets/imagens/tour-mapa-botao.jpg +0 -0
- package/src/studio/assets/imagens/tour-mapa-editor.jpg +0 -0
- package/src/studio/command-approval.js +2 -3
- package/src/studio/demo-decks.js +6 -2
- package/src/studio/export-jobs.js +86 -0
- package/src/studio/exporting.js +36 -18
- package/src/studio/feature-demos.js +144 -0
- package/src/studio/geo-routes.js +138 -0
- package/src/studio/ia-routes.js +9 -0
- package/src/studio/layout-samples.js +78 -16
- package/src/studio/library-routes.js +0 -9
- package/src/studio/project.js +2 -1
- package/src/studio/public/ai-settings.js +6 -3
- package/src/studio/public/app.js +46 -52
- package/src/studio/public/explorer.js +23 -8
- package/src/studio/public/export-status.js +154 -0
- package/src/studio/public/index.html +17 -10
- package/src/studio/public/library.css +12 -3
- package/src/studio/public/library.html +3 -0
- package/src/studio/public/library.js +39 -12
- package/src/studio/public/map-data.js +158 -0
- package/src/studio/public/map-editor.js +676 -0
- package/src/studio/public/map-fields.js +21 -0
- package/src/studio/public/map-settings.js +86 -0
- package/src/studio/public/slide-form.js +19 -16
- package/src/studio/public/style.css +58 -0
- package/src/studio/public/ui-icons.js +1 -1
- package/src/studio/public/viewers.js +2 -1
- package/src/studio/public/visual-editor.js +1 -1
- package/src/studio/server.js +34 -9
- package/src/studio/snapshot.js +8 -4
- package/src/studio/template-collections.js +1 -1
- package/src/studio/tour.js +158 -0
- package/src/themes.js +154 -0
- package/templates/cenario-e-ciencia.yaml +1 -21
- package/templates/ensaio-api.yaml +3 -3
- package/templates/cenario/Texto no cen/303/241rio.yaml" +0 -171
- package/templates/cenario/imagens/cidade.svg +0 -30
- package/templates/cenario/imagens/pessoa.svg +0 -15
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ Ele vem com 11 temas (incluindo prata limpo e respirável, artesanal desenhado
|
|
|
16
16
|
```bash
|
|
17
17
|
npm install -g sagadeck
|
|
18
18
|
```
|
|
19
|
-
Requer **Node.js
|
|
19
|
+
Requer **Node.js 22.13+** e **Chrome ou Edge** instalados (o PDF, o PNG e as conferências visuais usam o navegador).
|
|
20
20
|
É tudo Node: não precisa de Python. (O pacote do PyPI parou na 1.5.0.)
|
|
21
21
|
|
|
22
22
|
## Comece aqui
|
|
@@ -150,6 +150,48 @@ ilustrar" e `--no-images` proíbe. Imagens só são geradas para os slides que a
|
|
|
150
150
|
|
|
151
151
|
Todo YAML vindo do LLM é validado (renderiza cada slide); se falhar, o erro volta para o LLM corrigir (até 3 tentativas). Decks gerados passam por uma rodada de enxugamento quando o fiscal anti-sono reclamaria.
|
|
152
152
|
|
|
153
|
+
## Mapa (opcional)
|
|
154
|
+
|
|
155
|
+
O slide de mapa (`layout: map`) mostra pontos, linhas e áreas sobre um mapa ao vivo: sensores, medidores, unidades de
|
|
156
|
+
atendimento, cinemas, trajetos, bairros, o que for. Os dados vêm de uma planilha do projeto (CSV com latitude e
|
|
157
|
+
longitude, ou só com o endereço) ou de arquivos GeoJSON, GPX e KML. **Nada aqui é obrigatório**: quem não usa mapa
|
|
158
|
+
não precisa configurar coisa nenhuma, e o sagadeck não pede nada à internet por causa dele.
|
|
159
|
+
|
|
160
|
+
**Sem chave nenhuma, já funciona** com os serviços públicos gratuitos do OpenStreetMap:
|
|
161
|
+
|
|
162
|
+
| serviço | para quê | padrão (sem configurar) |
|
|
163
|
+
|---|---|---|
|
|
164
|
+
| mapa de fundo | as ruas por baixo das camadas | OpenStreetMap |
|
|
165
|
+
| fundos claro e escuro | dados sobre terra e mar, sem a linha de fronteira no mar | OpenFreeMap (vetorial) |
|
|
166
|
+
| endereço e coordenada | **Achar coordenadas** de uma planilha só com endereço | Nominatim (1 endereço por segundo) |
|
|
167
|
+
| busca de lugares | achar cinemas, escolas, unidades de saúde… pelo nome do tipo | Overpass |
|
|
168
|
+
| rotas | "seguir as ruas" ao desenhar, distância e tempo | OSRM (servidor de demonstração) |
|
|
169
|
+
|
|
170
|
+
**Chave opcional: OpenRouteService**, para rotas a pé, de carro e de bicicleta e para a **área alcançável em X
|
|
171
|
+
minutos**. É gratuita:
|
|
172
|
+
1. Crie a conta em [openrouteservice.org](https://openrouteservice.org) e confirme o e-mail.
|
|
173
|
+
2. No painel, gere um token do plano gratuito (Standard).
|
|
174
|
+
3. No Studio, **Configurar mapa** (no alto da biblioteca, ou no formulário do slide de mapa) › Rotas › **Usar o
|
|
175
|
+
OpenRouteService**, cole a chave e clique em **Testar**.
|
|
176
|
+
|
|
177
|
+
A configuração fica só nesta máquina, em `~/.sagadeck/mapa.json` (como a da IA); a chave nunca volta inteira para a
|
|
178
|
+
página e nunca vai para dentro da apresentação. Também vale pôr a chave numa variável de ambiente e indicar o nome dela
|
|
179
|
+
em `keyEnv` (no servidor, por exemplo):
|
|
180
|
+
|
|
181
|
+
```json
|
|
182
|
+
{ "rotas": { "provedor": "openrouteservice", "url": "https://api.openrouteservice.org", "keyEnv": "OPENROUTESERVICE_API_KEY" } }
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Os serviços públicos têm regras de uso que o sagadeck respeita sozinho: identifica os pedidos de dados, mostra as
|
|
186
|
+
atribuições do mapa, busca um endereço por segundo, guarda o que já achou e nunca baixa mapa fora da tela. O
|
|
187
|
+
[OpenFreeMap](https://openfreemap.org/) permite uso comercial e não exige cadastro ou chave. Os demais serviços
|
|
188
|
+
de demonstração servem para uso leve; para uma demanda maior, configure um provedor apropriado em **Configurar mapa**.
|
|
189
|
+
Os fundos claro e escuro também aceitam um estilo vetorial (JSON) ou tiles de um servidor próprio. Antes de mandar os endereços de uma planilha sua para um
|
|
190
|
+
serviço de fora, o sagadeck pergunta.
|
|
191
|
+
|
|
192
|
+
Se a rede barrar um serviço (autorização negada, proxy, bloqueio), o sagadeck faz **uma tentativa e para**: avisa
|
|
193
|
+
na tela, as camadas continuam desenhadas e nada é tentado de novo até você clicar em **Tentar de novo**.
|
|
194
|
+
|
|
153
195
|
## Desenvolvimento
|
|
154
196
|
|
|
155
197
|
```bash
|
|
@@ -192,6 +234,13 @@ formato avisa para atualizar o sagadeck. Se um filtro de e-mail barrar a extens
|
|
|
192
234
|
`sagadeck studio` sem arquivo abre a biblioteca: suas apresentações organizadas em tópicos, com capa, busca,
|
|
193
235
|
lixeira (30 dias; o prazo se muda em Preferências) e o menu **⋯** de cada cartão (apresentar, renomear, duplicar, mover, baixar tudo/.sagadeck/PPTX/PDF).
|
|
194
236
|
|
|
237
|
+
Na lateral, **Demos oficiais** (com cadeado) guarda as apresentações do próprio SagaDeck, só leitura. Primeiro, as
|
|
238
|
+
demos de um assunto só, curtas: **Mapas** (mostrar, calcular e editar), **Programação** (código destacado e guiado,
|
|
239
|
+
código que a plateia roda, algoritmo animado, Git a dois, diagramas) e **APIs com curl** (a anatomia de um curl e
|
|
240
|
+
chamadas ao vivo com o curl para copiar, rodando na API de mentira do Studio). Depois, o **Conheça o SagaDeck** (um
|
|
241
|
+
slide por recurso, cada um com a frase para pedir à IA) e as outras demos de recursos. Elas abrem em prévia, sem criar arquivo; editar cria uma cópia sua em Modelos. O Conheça o SagaDeck
|
|
242
|
+
aparece também como o primeiro cartão de Recentes e Todas.
|
|
243
|
+
|
|
195
244
|
**Nova apresentação** tem três caminhos: *Descrever com IA* (o assunto, quanto tempo você tem, que vira o número de
|
|
196
245
|
slides, o estilo e, se quiser, material de apoio: PDF, Word, PowerPoint, Excel ou um link), *A partir de um arquivo
|
|
197
246
|
ou link* (o mesmo, começando pelo anexo) e *Modelo pronto* (coleções, estilos, demonstrações e exemplos, com filtro).
|
|
@@ -244,9 +293,11 @@ token nunca vai para a página.
|
|
|
244
293
|
|
|
245
294
|
Para ver funcionando sem configurar nada:
|
|
246
295
|
|
|
247
|
-
- **
|
|
248
|
-
ambiente **ENSAIO**: uma API de mentira que o Studio sobe sozinho (sem VPN, sem
|
|
249
|
-
|
|
296
|
+
- **Demos oficiais → APIs com curl.** As chamadas mais comuns (corpo, consulta na URL, token, polling, streaming),
|
|
297
|
+
cada uma com o curl, rodando no ambiente **ENSAIO**: uma API de mentira que o Studio sobe sozinho (sem VPN, sem
|
|
298
|
+
chave). Apresente e clique em **Executar**.
|
|
299
|
+
- **`sagadeck ensaio-api`.** O ensaio completo, com um slide de cada tipo (upload, OCR, embeddings, voz, tempo
|
|
300
|
+
real), no mesmo ambiente ENSAIO. O deck também traz um slide
|
|
250
301
|
**OpenRouter (real)** com `nvidia/nemotron-3-super-120b-a12b:free`. Para usá-lo, defina `OPENROUTER_API_KEY` no
|
|
251
302
|
processo que inicia o Studio e escolha o ambiente **OPENROUTER** no selo do slide. A chave fica fora do
|
|
252
303
|
deck; no PowerShell, por exemplo, defina `$env:OPENROUTER_API_KEY = "sua-chave"` antes de iniciar o
|
package/SKILL.md
CHANGED
|
@@ -11,7 +11,7 @@ O sagadeck gera apresentações profissionais a partir de um arquivo YAML, ofere
|
|
|
11
11
|
|
|
12
12
|
Quando a pessoa pede para instalar o sagadeck e deixar pronto:
|
|
13
13
|
|
|
14
|
-
1. `npm install -g sagadeck` (Node
|
|
14
|
+
1. `npm install -g sagadeck` (Node 22.13+; não precisa de Python).
|
|
15
15
|
2. `sagadeck studio`: o navegador abre sozinho em **http://127.0.0.1:3517** (é também a primeira linha que o
|
|
16
16
|
comando escreve; `--sem-navegador` não abre). **O Studio é a interface do sagadeck**: biblioteca, editor e chat com
|
|
17
17
|
IA. O terminal fica aberto enquanto ela usa.
|
|
@@ -20,7 +20,12 @@ Quando a pessoa pede para instalar o sagadeck e deixar pronto:
|
|
|
20
20
|
4. Para a IA, mostre onde configurar: **Configurar IA** no alto da biblioteca (ou **IA desligada** no editor):
|
|
21
21
|
**Usar a recomendação** (OpenRouter com modelos que funcionam), a chave, Testar e Salvar. A configuração fica em `~/.sagadeck/ia.json`; nunca grave a chave no código nem
|
|
22
22
|
na pasta das apresentações.
|
|
23
|
-
5.
|
|
23
|
+
5. **Para saber o que de IA funciona**, rode `sagadeck ia-check` (ou a ferramenta `sagadeck_ia_check` do MCP) antes de
|
|
24
|
+
prometer qualquer recurso de IA: testa texto, visão, geração de imagem, pesquisa e vídeo com chamadas de verdade, em
|
|
25
|
+
paralelo, em segundos. Cada recurso sai `OK`, `FALHOU` (com o motivo), `SEM CONFIG` ou, no vídeo, `SEM PROVA`: por
|
|
26
|
+
padrão o vídeo não é gerado (é cobrado); só `--video-real` prova que funciona, e só rode quando a pessoa pedir.
|
|
27
|
+
`--json` para ler a saída; o comando sai com código 1 se algo falhou.
|
|
28
|
+
6. As apresentações moram na biblioteca (`SAGADECK_HOME`, senão Documentos\sagadeck no Windows e `~/sagadeck` fora
|
|
24
29
|
dele). Não crie decks em outra pasta.
|
|
25
30
|
|
|
26
31
|
## Comandos Disponíveis
|
|
@@ -30,6 +35,7 @@ Quando a pessoa pede para instalar o sagadeck e deixar pronto:
|
|
|
30
35
|
| `sagadeck studio [deck.yaml] [--port=3517]` | **Abre o estúdio web estilo PowerPoint** com canvas visual 16:9, edição WYSIWYG direta, detector de sobreposição em tempo real e **chat lateral com IA**. |
|
|
31
36
|
| `sagadeck autofix <deck.yaml>` | **Auto-cura do layout**: detecta e repara automaticamente sobreposição entre elementos, elementos fora das margens seguras (120px) e excesso de texto. |
|
|
32
37
|
| `sagadeck search "<termo>"` | **Pesquisa web sem bloqueio (DuckDuckGo)**: busca dados reais, números e referências confiáveis para enriquecer os slides. |
|
|
38
|
+
| `sagadeck ia-check [--rapido] [--so=texto,visao,imagem,pesquisa,video] [--video-real] [--json]` | **Testa a IA configurada sem tela**: cada recurso com uma chamada de verdade, todos ao mesmo tempo; `--rapido` pula imagem e vídeo; `--video-real` gera um clipe curto (cobrado). Código de saída 1 se algo falhou |
|
|
33
39
|
| `sagadeck mcp` | **Servidor MCP**: expõe ferramentas padronizadas (JSON-RPC) para IDEs agênticos criarem, lerem, pesquisarem, fiscalizarem e editarem decks. |
|
|
34
40
|
| `sagadeck new "<nome>" [--topic=T] [--theme=prata]` | cria um deck de exemplo na biblioteca |
|
|
35
41
|
| `sagadeck build deck.yaml` | compila `deck.html` standalone (abre no navegador; tecla P = modo apresentador) |
|
|
@@ -107,6 +113,7 @@ Ferramentas disponíveis no MCP:
|
|
|
107
113
|
- `sagadeck_autofix_deck`: executa a auto-cura geométrica no arquivo YAML.
|
|
108
114
|
- `sagadeck_build_html`: compila o arquivo `.html` interativo.
|
|
109
115
|
- `sagadeck_launch_studio`: abre o SagaDeck Studio na web.
|
|
116
|
+
- `sagadeck_ia_check`: testa a IA configurada (texto, visão, imagem, pesquisa, vídeo), em paralelo, e diz o que funciona.
|
|
110
117
|
|
|
111
118
|
### 2. Via Linha de Comando (CLI)
|
|
112
119
|
O agente no terminal deve seguir o fluxo:
|
|
@@ -151,6 +158,6 @@ Para apresentações de alto impacto sem "muralhas de texto":
|
|
|
151
158
|
|
|
152
159
|
## Recursos recentes para autoria por IA
|
|
153
160
|
|
|
154
|
-
Consulte `docs/REFERENCIA.md` para os contratos atuais de `science` (KaTeX, até cinco equações, Plotly 2D/3D), `
|
|
161
|
+
Consulte `docs/REFERENCIA.md` para os contratos atuais de `science` (KaTeX, até cinco equações, Plotly 2D/3D), `spotlight`, `codewalk` e `api`. Para criar apresentações autonomamente, a IA precisa desta referência, do briefing, do material autorizado e das imagens; acesso ao banco por si só não transmite o formato do SagaDeck. Use apenas endpoints/status reais fornecidos pela documentação interna, sem inventar detalhes. Configure credenciais no ambiente local; nunca dentro dos slides.
|
|
155
162
|
|
|
156
163
|
O Studio permite inserir e arrastar elementos e revisar uma imagem do slide com IA. Ajustes manuais `visualEdits` são específicos da estrutura renderizada: remova-os ao reconstruir um slide. Sempre confira o resultado renderizado; regras geométricas não garantem qualidade visual.
|
package/bin/sagadeck.js
CHANGED
|
@@ -76,6 +76,11 @@ const HELP = `sagadeck — YAML -> apresentação (HTML animado + PowerPoint edi
|
|
|
76
76
|
sagadeck autofix <deck.yaml> [--out=pasta] auto-corrige sobreposições, margens e excesso de texto no YAML
|
|
77
77
|
sagadeck diff <a.yaml> <b.yaml> [--json] o que entrou, saiu, mudou e andou entre dois decks (por uid)
|
|
78
78
|
sagadeck enxugar <deck.yaml> [--fix] palavras por slide contra o limite do material (--fix: excedente para as notas)
|
|
79
|
+
sagadeck ia-check [--rapido] [--so=texto,visao,imagem,pesquisa,video] [--video-real] [--json]
|
|
80
|
+
testa a IA configurada, sem tela: cada recurso com uma chamada de verdade, todos ao
|
|
81
|
+
mesmo tempo, cada resultado assim que chega. --rapido pula imagem e vídeo; vídeo, por
|
|
82
|
+
padrão, só confere chave e catálogo; --video-real gera um clipe curto (é cobrado).
|
|
83
|
+
Sai com erro se algo falhou (bom para agentes e CI); --json para máquina
|
|
79
84
|
sagadeck mcp inicia o servidor MCP para IDEs agênticos (Cursor, Claude Code, Cline)
|
|
80
85
|
sagadeck watch <deck.yaml> recompila o HTML sempre que o YAML mudar
|
|
81
86
|
sagadeck themes [--out=pasta] gera uma vitrine com todos os temas
|
|
@@ -490,6 +495,24 @@ async function main() {
|
|
|
490
495
|
}
|
|
491
496
|
break;
|
|
492
497
|
}
|
|
498
|
+
case "ia-check": case "testar-ia": {
|
|
499
|
+
const { iaCheck, CHECKS } = await import("../src/ai/ia-check.js");
|
|
500
|
+
const only = flags.so ? String(flags.so).split(",").map((x) => x.trim().normalize("NFD").replace(/[̀-ͯ]/g, "")).filter(Boolean) : null;
|
|
501
|
+
const bad = (only || []).filter((x) => !CHECKS[x]);
|
|
502
|
+
if (bad.length) { console.error(`Recurso desconhecido: ${bad.join(", ")}. Vale: ${Object.keys(CHECKS).join(", ")}`); process.exit(2); }
|
|
503
|
+
const json = !!flags.json, log = json ? (...a) => console.error(...a) : (...a) => console.log(...a);
|
|
504
|
+
const SELO = { ok: "OK ", falhou: "FALHOU ", nao_configurado: "SEM CONFIG", sem_prova: "SEM PROVA " };
|
|
505
|
+
const seg = (ms) => `${(ms / 1000).toFixed(1).replace(".", ",")} s`;
|
|
506
|
+
log(`Testando a IA em paralelo${flags["video-real"] ? " (vídeo: gera um clipe de verdade, é cobrado)" : ""}…`);
|
|
507
|
+
const rep = await iaCheck({ only, rapido: !!flags.rapido, videoReal: !!flags["video-real"], videoTimeoutS: Number(flags["video-prazo"] || 600),
|
|
508
|
+
onResult: (r) => log(` ${SELO[r.status] || r.status} ${r.nome.padEnd(18)} ${seg(r.ms).padStart(7)} ${r.modelo ? r.modelo + " · " : ""}${r.detalhe || ""}${r.arquivo ? ` · ${r.arquivo}` : ""}`) });
|
|
509
|
+
const n = (st) => rep.resultados.filter((r) => r.status === st).length;
|
|
510
|
+
log(`${n("ok")} de ${rep.resultados.length} funcionando${n("falhou") ? `, ${n("falhou")} com falha` : ""}${n("nao_configurado") ? `, ${n("nao_configurado")} sem configuração` : ""}${n("sem_prova") ? `, ${n("sem_prova")} sem prova (use --video-real)` : ""} · ${seg(rep.ms)}`);
|
|
511
|
+
if (json) console.log(JSON.stringify(rep, null, 2));
|
|
512
|
+
// sai na hora: conexões que o provedor deixa abertas seguravam o processo por dezenas de segundos
|
|
513
|
+
process.stdout.write("", () => process.exit(rep.ok ? 0 : 1));
|
|
514
|
+
break;
|
|
515
|
+
}
|
|
493
516
|
case "mcp": {
|
|
494
517
|
const { runMCPServer } = await import("../src/mcp/server.js");
|
|
495
518
|
runMCPServer();
|