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.
Files changed (105) hide show
  1. package/README.md +55 -4
  2. package/SKILL.md +10 -3
  3. package/bin/sagadeck.js +23 -0
  4. package/docs/ANDAMENTO.md +483 -1
  5. package/docs/PLANO-MELHORIAS.md +180 -0
  6. package/docs/REFERENCIA.md +184 -105
  7. package/package.json +34 -2
  8. package/src/ai/commands.js +2 -2
  9. package/src/ai/deck-ai.js +14 -5
  10. package/src/ai/ia-check.js +127 -0
  11. package/src/ai/ia-config.js +2 -2
  12. package/src/ai/llm.js +5 -1
  13. package/src/ai/map-analysis-run.js +119 -0
  14. package/src/ai/map-data.js +221 -0
  15. package/src/ai/quality.js +1 -1
  16. package/src/ai/video-generation.js +70 -25
  17. package/src/build.js +51 -15
  18. package/src/elements.js +39 -1
  19. package/src/export/browser.js +23 -1
  20. package/src/export/pptx.js +9 -3
  21. package/src/export/shots.js +10 -3
  22. package/src/fiscal/normalize.js +19 -0
  23. package/src/fs-retry.js +37 -2
  24. package/src/import/office.js +5 -4
  25. package/src/layouts.js +114 -99
  26. package/src/lessons.js +1 -1
  27. package/src/library.js +7 -7
  28. package/src/map-analysis.js +109 -0
  29. package/src/map-config.js +89 -0
  30. package/src/map-routing.js +82 -0
  31. package/src/map-services.js +60 -0
  32. package/src/map.js +274 -0
  33. package/src/mcp/server.js +17 -0
  34. package/src/motion.js +20 -6
  35. package/src/purpose.js +1 -1
  36. package/src/runtime/base.css +105 -329
  37. package/src/runtime/fit.js +3 -2
  38. package/src/runtime/fonts/amatic-sc.css +3 -0
  39. package/src/runtime/fonts/bebas-neue.css +2 -0
  40. package/src/runtime/fonts/cabin-sketch.css +2 -0
  41. package/src/runtime/fonts/fraunces.css +3 -0
  42. package/src/runtime/fonts/gelasio.css +3 -0
  43. package/src/runtime/fonts/ibm-plex-mono.css +4 -0
  44. package/src/runtime/fonts/index.json +10 -1
  45. package/src/runtime/fonts/itim.css +2 -0
  46. package/src/runtime/fonts/montserrat.css +2 -0
  47. package/src/runtime/fonts/space-grotesk.css +2 -0
  48. package/src/runtime/map-background.js +91 -0
  49. package/src/runtime/map.js +266 -0
  50. package/src/runtime/runtime.js +81 -100
  51. package/src/runtime/skins/caderno.css +33 -0
  52. package/src/runtime/skins/cartaz.css +27 -0
  53. package/src/runtime/skins/infografico.css +29 -0
  54. package/src/runtime/skins/lousa.css +22 -0
  55. package/src/runtime/skins/musgo.css +42 -0
  56. package/src/runtime/vendor/LEAFLET-LICENSE.txt +26 -0
  57. package/src/runtime/vendor/MAPLIBRE-LEAFLET-LICENSE.txt +15 -0
  58. package/src/runtime/vendor/MAPLIBRE-LICENSE.txt +116 -0
  59. package/src/runtime/vendor/geo-contornos.json +1 -0
  60. package/src/runtime/vendor/leaflet.css +661 -0
  61. package/src/runtime/vendor/leaflet.js +6 -0
  62. package/src/runtime/vendor/maplibre-gl.css +1 -0
  63. package/src/runtime/vendor/maplibre-gl.js +825 -0
  64. package/src/runtime/vendor/maplibre-leaflet.js +234 -0
  65. package/src/runtime/vendor/maplibre-worker.js +10 -0
  66. package/src/studio/ai-chat-route.js +20 -0
  67. package/src/studio/assets/imagens/tour-mapa-botao.jpg +0 -0
  68. package/src/studio/assets/imagens/tour-mapa-editor.jpg +0 -0
  69. package/src/studio/command-approval.js +2 -3
  70. package/src/studio/demo-decks.js +6 -2
  71. package/src/studio/export-jobs.js +86 -0
  72. package/src/studio/exporting.js +36 -18
  73. package/src/studio/feature-demos.js +144 -0
  74. package/src/studio/geo-routes.js +138 -0
  75. package/src/studio/ia-routes.js +9 -0
  76. package/src/studio/layout-samples.js +78 -16
  77. package/src/studio/library-routes.js +0 -9
  78. package/src/studio/project.js +2 -1
  79. package/src/studio/public/ai-settings.js +6 -3
  80. package/src/studio/public/app.js +46 -52
  81. package/src/studio/public/explorer.js +23 -8
  82. package/src/studio/public/export-status.js +154 -0
  83. package/src/studio/public/index.html +17 -10
  84. package/src/studio/public/library.css +12 -3
  85. package/src/studio/public/library.html +3 -0
  86. package/src/studio/public/library.js +39 -12
  87. package/src/studio/public/map-data.js +158 -0
  88. package/src/studio/public/map-editor.js +676 -0
  89. package/src/studio/public/map-fields.js +21 -0
  90. package/src/studio/public/map-settings.js +86 -0
  91. package/src/studio/public/slide-form.js +19 -16
  92. package/src/studio/public/style.css +58 -0
  93. package/src/studio/public/ui-icons.js +1 -1
  94. package/src/studio/public/viewers.js +2 -1
  95. package/src/studio/public/visual-editor.js +1 -1
  96. package/src/studio/server.js +34 -9
  97. package/src/studio/snapshot.js +8 -4
  98. package/src/studio/template-collections.js +1 -1
  99. package/src/studio/tour.js +158 -0
  100. package/src/themes.js +154 -0
  101. package/templates/cenario-e-ciencia.yaml +1 -21
  102. package/templates/ensaio-api.yaml +3 -3
  103. package/templates/cenario/Texto no cen/303/241rio.yaml" +0 -171
  104. package/templates/cenario/imagens/cidade.svg +0 -30
  105. 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 18+** e **Chrome ou Edge** instalados (o PDF, o PNG e as conferências visuais usam o navegador).
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
- - **Biblioteca → Nova → Exemplo: aula de APIs ao vivo.** Cria um deck com um slide de cada tipo, que roda no
248
- ambiente **ENSAIO**: uma API de mentira que o Studio sobe sozinho (sem VPN, sem chave). Apresente e clique
249
- em **Executar**. (`sagadeck ensaio-api` faz o mesmo pela linha de comando.) O deck também traz um slide
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 18+; não precisa de Python).
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. As apresentações moram na biblioteca (`SAGADECK_HOME`, senão Documentos\sagadeck no Windows e `~/sagadeck` fora
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), `scenography` (texto integrado ao cenário, estático), `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.
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();