sagadeck 1.9.0 → 1.11.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 (56) hide show
  1. package/README.md +9 -2
  2. package/SKILL.md +1 -1
  3. package/bin/sagadeck.js +1 -1
  4. package/docs/ANDAMENTO.md +302 -0
  5. package/docs/REFERENCIA.md +72 -4
  6. package/package.json +4 -4
  7. package/src/ai/context.js +7 -2
  8. package/src/ai/critique.js +8 -1
  9. package/src/ai/deck-ai.js +36 -12
  10. package/src/ai/document-visuals.js +6 -2
  11. package/src/ai/ia-check.js +13 -4
  12. package/src/ai/ia-config.js +4 -2
  13. package/src/ai/llm.js +12 -7
  14. package/src/ai/math-check.js +318 -0
  15. package/src/ai/quality.js +3 -3
  16. package/src/ai/units.js +85 -0
  17. package/src/api-client.js +42 -10
  18. package/src/build.js +1 -0
  19. package/src/code-highlight.js +19 -2
  20. package/src/code-language.js +13 -0
  21. package/src/fs-retry.js +2 -2
  22. package/src/lessons.js +72 -11
  23. package/src/mcp/server.js +1 -1
  24. package/src/package.js +4 -0
  25. package/src/runtime/api-core.js +122 -11
  26. package/src/runtime/api-ui.js +2 -1
  27. package/src/runtime/base.css +3 -0
  28. package/src/runtime/skins/aurora-dev.css +39 -0
  29. package/src/runtime/skins/terminal-pro.css +33 -0
  30. package/src/runtime/solution.js +131 -0
  31. package/src/studio/ai-chat-route.js +69 -7
  32. package/src/studio/conference-routes.js +44 -0
  33. package/src/studio/conference.js +144 -0
  34. package/src/studio/developer-starters.js +46 -0
  35. package/src/studio/generation-report.js +61 -1
  36. package/src/studio/generation-request.js +80 -0
  37. package/src/studio/ia-routes.js +1 -1
  38. package/src/studio/layout-samples.js +1 -1
  39. package/src/studio/library-routes.js +7 -0
  40. package/src/studio/public/about.js +68 -0
  41. package/src/studio/public/ai-settings.js +4 -4
  42. package/src/studio/public/app.js +14 -2
  43. package/src/studio/public/chat.js +11 -3
  44. package/src/studio/public/conference-ui.js +91 -0
  45. package/src/studio/public/developer-authoring.css +12 -0
  46. package/src/studio/public/developer-authoring.js +306 -0
  47. package/src/studio/public/generation-guide.js +42 -0
  48. package/src/studio/public/index.html +21 -0
  49. package/src/studio/public/library.css +36 -0
  50. package/src/studio/public/library.html +4 -1
  51. package/src/studio/public/library.js +118 -28
  52. package/src/studio/public/slide-form.js +17 -17
  53. package/src/studio/public/style.css +25 -0
  54. package/src/studio/public/ui-icons.js +1 -1
  55. package/src/studio/server.js +20 -8
  56. package/src/themes.js +48 -0
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 22.13+** e **Chrome ou Edge** instalados (o PDF, o PNG e as conferências visuais usam o navegador).
19
+ Requer **Node.js 24+** 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
@@ -96,6 +96,7 @@ de cada papel:
96
96
  | visão | ver o slide renderizado e as imagens coladas | opcional; vazio = o de texto |
97
97
  | imagem | ilustrações (`image_prompt`) | opcional |
98
98
  | busca | pesquisa na web da geração (no OpenRouter, um modelo `:online`) | opcional; sem ele, buscadores diretos |
99
+ | conferir | as conferências: contas, leitura crítica e confirmação da revisão visual (um modelo de raciocínio mais forte só onde a conta precisa estar certa) | opcional; vazio = o de texto |
99
100
 
100
101
  **Testar** faz uma pergunta curta com o que está na tela antes de salvar. A configuração fica só nesta máquina, em
101
102
  `~/.sagadeck/ia.json` (fora do código e fora da biblioteca, que pode sincronizar com a nuvem); a chave nunca volta
@@ -138,7 +139,7 @@ As variáveis abaixo valem por cima da configuração (útil em servidor e em te
138
139
  |---|---|
139
140
  | `SAGADECK_LLM_URL` | qualquer API compatível com OpenAI (ex.: `https://openrouter.ai/api/v1`) |
140
141
  | `SAGADECK_LLM_KEY` | a chave (bearer token) |
141
- | `SAGADECK_TEXT_MODEL` / `SAGADECK_VISION_MODEL` / `SAGADECK_IMAGE_MODEL` / `SAGADECK_SEARCH_MODEL` | os modelos de cada papel |
142
+ | `SAGADECK_TEXT_MODEL` / `SAGADECK_VISION_MODEL` / `SAGADECK_IMAGE_MODEL` / `SAGADECK_SEARCH_MODEL` / `SAGADECK_CHECK_MODEL` | os modelos de cada papel (`CHECK`: o das conferências) |
142
143
  | `SAGADECK_LLM_TIMEOUT` | segundos por chamada (padrão `180`) |
143
144
  | `SAGADECK_IA` | outro arquivo de configuração (padrão `~/.sagadeck/ia.json`) |
144
145
 
@@ -285,6 +286,12 @@ navegador, mas não para editar.
285
286
 
286
287
  ## Slides para devs: API ao vivo
287
288
 
289
+ Na biblioteca, **Programação** e **APIs com cURL** abrem a criação com exemplos de pedidos, código colado,
290
+ anexos técnicos e prévia do briefing. Também há duas bases curtas para começar **sem IA**.
291
+ No editor, **Início ou Inserir → Código / cURL** transforma conteúdo colado em código, explicação guiada
292
+ ou requisição de API. Selecione linhas para criar as etapas; Bash/cURL, JSON e SQL têm realce offline.
293
+ Os temas **Terminal Pro** e **Aurora Dev**, em Design, trazem código legível e capas com rede animada.
294
+
288
295
  O layout `api` é um slide tipo Postman: mostra o pedido (URL, corpo, cabeçalhos) e o código equivalente
289
296
  (curl, Python e Python comentado), e o botão **Executar** roda o pedido de verdade na frente da plateia:
290
297
  síncrono, polling com linha do tempo, streaming, upload, token (JWT decodificado), embeddings, TTS/STT e
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 22.13+; não precisa de Python).
14
+ 1. `npm install -g sagadeck` (Node 24+; 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.
package/bin/sagadeck.js CHANGED
@@ -76,7 +76,7 @@ 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]
79
+ sagadeck ia-check [--rapido] [--so=texto,visao,imagem,pesquisa,video,conferencia] [--video-real] [--json]
80
80
  testa a IA configurada, sem tela: cada recurso com uma chamada de verdade, todos ao
81
81
  mesmo tempo, cada resultado assim que chega. --rapido pula imagem e vídeo; vídeo, por
82
82
  padrão, só confere chave e catálogo; --video-real gera um clipe curto (é cobrado).
package/docs/ANDAMENTO.md CHANGED
@@ -8,6 +8,308 @@ começar. Trabalho em curso vai para o GitHub (commit + push) a cada etapa, nunc
8
8
 
9
9
  ---
10
10
 
11
+ ## Conversão para a unidade do resultado — 23/10/2026 (branch `claude/unidade-resultado`)
12
+
13
+ Terceiro pedido à IA na cópia da Narumi, em produção (`020c243`): ela resolveu as pendências dos slides 12, 23 e 24,
14
+ mas a conferência das contas acusou falsos alarmes ("107 L/s dá 106.400", "120 cm dá 12.000"): o modelo escreveu a
15
+ conversão para a unidade do resultado na fórmula (`*1000` para L/s, `*100` para cm) e o código convertia de novo.
16
+ A detecção de conversão feita à mão olhava só as unidades das vars; agora olha também a do resultado. Conferido no
17
+ deck: os slides 21, 22 e 27 que a correção mexeu continuaram certos (273 m; 944 cm e sobra de 273 cm; velocidades
18
+ 0,64 / 0,605 / 0,58 m/s).
19
+ Um ensaio em memória com o modelo real mostrou que o problema é maior: o modelo rotula mal as unidades (kPa num
20
+ lugar, N/m³ no outro) e a conta com unidades sai mil vezes errada ("273 m dá 937045"); empurrada pelos alarmes, a
21
+ correção enfeitou o slide 21 com "= 100 × 2,729 m". Regra nova (`judge`): a conta bate se bater nos números dados
22
+ OU com a conversão; só é divergência o que não bate de jeito nenhum. As unidades servem para evitar alarme falso,
23
+ nunca para criar um. Saiu a acusação da fórmula do slide por unidades (`fn_slide`), que deu alarme falso no deck
24
+ real. Testes: `units.test.js` (rótulo errado não acusa; L/s só bate com a conversão; erro de verdade acusa) e ao
25
+ vivo (resultado certo em L/s e cm não vira alarme; 600 s → 240 s com a resposta calculada pelo motor).
26
+
27
+ ## Ajustes depois do teste na cópia — 23/10/2026 (branch `claude/ajustes-conferencia`)
28
+
29
+ Teste em produção na cópia da Narumi (nunca no deck da Mary): a IA, pelo chat, corrigiu as contas (21: 273 m;
30
+ 22: gráfico com 944 cm disponíveis e a sobra de 272 cm; 25: D ≈ 0,17 m, comercial 0,20 m, hf 1,29 m com "Confira"
31
+ nas notes) e depois os avisos da criação (slides 5, 6, 9, 11, 15, 16, 18, 22). Três ajustes:
32
+ - a conferência deixou um aviso falso ("273 m dá 617,8": fórmula errada do verificador; a IA que corrige disse que
33
+ o slide estava certo). Agora, quando ela discorda, uma conferência independente decide; o aviso só fica se as
34
+ duas acusarem (`math.contestadas` conta os que caíram).
35
+ - a resposta do chat trazia `</parameter>` solto (formato de ferramenta do modelo): `cleanProse` tira essas
36
+ marcas, sem mexer em HTML da pessoa.
37
+ - dado `p_atm` no exercício aparecia "pₐtm": índice de várias letras ganha chaves (`symbolTex` em `src/lessons.js`).
38
+ - o painel Revisar › Conferência seguia com os 24 avisos visuais mesmo depois de a IA corrigir os slides pelo chat.
39
+ O relatório guarda a impressão digital de cada slide (`slideMarks`; relatório antigo usa a versão mais antiga
40
+ guardada em `.sagadeck/versoes/`): aviso de slide que mudou aparece como "o slide mudou; confira se ainda vale" e
41
+ não vai mais à IA como pendência.
42
+ - o selo da Conferência consultava o servidor a cada troca de slide; agora só quando o deck é salvo (e na abertura
43
+ e no fim de cada pedido ao chat). `perf.test.js` conta as consultas durante a navegação (falhou com 4, passa com 0).
44
+ O teste de desempenho com 200 slides também falha às vezes nesta máquina com uma troca de 4–5 s, inclusive em
45
+ commits de antes destas mudanças (`3c18855`, `df0f7df`): instabilidade da máquina, não regressão (a CI passa).
46
+ Testes em `ai.test.js` e `engine.test.js`; os ajustes falham sem o conserto.
47
+
48
+ ## Arquivo travado no Windows — 23/10/2026 (branch `claude/rename-windows`)
49
+
50
+ A CI da main falhou no Windows depois do #201: o rename atômico do deck deu EPERM por mais tempo que as novas
51
+ tentativas (~1 s) e o teste do formulário do slide api leu o deck sem a última mudança (as rodadas seguintes
52
+ passaram). `RENAME_DELAYS` agora espera até ~4 s (OneDrive/antivírus da pessoa também ganham). Teste novo em
53
+ `deck-file.test.js` simula o arquivo travado por 1,5 s: falhou antes, passa agora.
54
+
55
+ ## Contas calculadas no exercício resolvido — 22/10/2026 (branch `claude/unruffled-nobel-8f9bce`, parte de `claude/conferir-contas`)
56
+
57
+ A raiz do "L₁ ≈ 55 m": o número do passo era texto da IA. Agora, no `solution`, o número nasce da conta.
58
+ - `src/runtime/solution.js` (motor e apresentação, como o `calc.js`): dados com `symbol` + `value` numérico viram
59
+ variáveis (nome do símbolo: `L_1` → `L1`, `\rho` → `rho`; ou `name`); passo e resposta com `fn` são calculados na
60
+ ordem pelo compilador de `formula.js` (sem eval). Valor no fim do LaTeX do passo (`≈`, ou `=` se exato) ou onde
61
+ estiver `{{nome}}` (o próprio nome do passo); `{{nome}}`/`{{expr:casas}}` também nos textos, resposta e enunciado.
62
+ Vírgula decimal, milhar (`\,` na fórmula, ponto no texto), `decimals` ou 4 algarismos.
63
+ - Erro na fórmula ou letra sem valor: aviso de render ("exercício resolvido: passo 2: a fórmula usa "k"…") e caixa
64
+ `.sol-error` no passo; o valor vira traço, sem LaTeX quebrado. A IA recebe o aviso como qualquer outro.
65
+ - `interactive: true`: controle deslizante em cada dado (passo na grade das casas do dado; min/max alinhados, senão
66
+ 0,01 virava 0,011), Restaurar, números trocados ao vivo por marcas `\htmlData{solv=k}` (KaTeX com `trust` só para
67
+ esse atributo) e `<span data-solv>` no texto. Só nesse modo o HTML leva as marcas; o estático segue limpo.
68
+ O MathML não acompanha o número novo: no modo interativo ele some e o leitor de tela lê o próprio desenho.
69
+ Carregado em `build.js` só com `solution` interativo; Studio serve `/solution.js` e monta no editor.
70
+ - `math-check.js`: `forAudit` tira os passos/resposta com `fn` e troca `{{…}}` por "(calculado)"; `hasMath` de um
71
+ exercício com `fn` só é verdade se sobrar número escrito à mão.
72
+ - Formulário (fórmula, nome, unidade, casas do passo; nome/mín./máx. do dado; "Dados ajustáveis"), exemplo da galeria
73
+ (juros com `fn` e interativo), `REFERENCIA.md` (seção + exemplo do sifão, que renderiza sem aviso) e o prompt
74
+ ("nunca escreva à mão um resultado que uma fórmula dá").
75
+ - Testes em `test/lessons.test.js` (onde o `solution` já mora): render com valores e arredondamento, erro claro,
76
+ conferência que pula o calculado, apresentação interativa e o formulário do Studio conferido no deck salvo.
77
+
78
+ ## Unidades e contas do material — 23/10/2026 (branch `claude/conferir-unidades`, worktree `../sagadeck-conferir-unidades`)
79
+
80
+ Continuação da conferência das contas (#201), sugestões 3 e 4 da revisão do deck da Mary.
81
+ - `src/ai/units.js`: unidades comuns de aula e relatório (m, cm, L/s, kN/m², mH2O, °C, %…) → fator para o SI e
82
+ dimensão. `dimensionOf` acha a dimensão de uma conta sem árvore de expressão: escala cada grandeza de base (×2, ×3)
83
+ e vê como o resultado muda; soma de grandezas diferentes não muda como potência e é apontada.
84
+ - Conferência das contas com unidades: a IA dá a unidade de cada var; a conta é feita no SI e volta para a unidade
85
+ do slide (L/s × m³/s, cm × m deixam de dar falso erro; 611 m/s no lugar de 0,611 é pego). `fn_slide` (a fórmula
86
+ como o slide escreveu) é acusada quando não fecha em unidades, só se a conta da própria IA fecha. Conversão feita
87
+ à mão pela IA (Q/1000 com Q em L/s) não é convertida de novo; resultado sem unidade fica no SI.
88
+ - Leitura crítica confere as contas do próprio material (`auditMaterialMath`): duas rodadas independentes em
89
+ paralelo, só fica o que as duas acusam (o modelo real errou a conversão numa rodada); vira item `inconsistencia`
90
+ com trecho literal conferido. Usa o modelo das conferências (#202).
91
+ Testes: `units.test.js` (unidades, dimensão, conversão, fórmula do slide), `critique.test.js` (gabarito errado vira
92
+ item, rodadas que discordam não viram aviso), ao vivo (`SAGADECK_LIVE=1`): conversão esquecida e lista com
93
+ gabarito errado, 3 de 3. Suíte completa da branch antes da integração: 1.117 testes, 1.086 aprovados, zero falhas.
94
+ Integração com #202, #203 e #204 (base `claude/laughing-ritchie-81bb23`): conflito só na REFERENCIA, as duas frases
95
+ ficaram.
96
+
97
+ ## Painel Revisar › Conferência — 22/10/2026 (branch `claude/laughing-ritchie-81bb23`, sobre `claude/conferir-contas`)
98
+
99
+ Continuação da conferência das contas (abaixo): os achados das checagens tinham aviso, mas não tinham lugar nem
100
+ botão (relatório num arquivo, uma mensagem do chat na primeira abertura, selo de origem na miniatura). Agora:
101
+ - Revisar › **Conferência** (ao lado de Mudanças), com selo da contagem pendente: por slide, contas que não batem,
102
+ contas do material que não fecham, números sem base no material, avisos da revisão visual, figuras do material sem
103
+ slide e slides `derivado`/`proprio`. Montado no servidor (`src/studio/conference.js`) a partir do relatório
104
+ (`.sagadeck/avaliacao-geracao.json`) e do deck atual; achado que o deck já não tem (o número saiu do slide, o
105
+ slide não existe) some sozinho. Tela em `src/studio/public/conference-ui.js`.
106
+ - Por item: Ir ao slide; **Corrigir com IA** (pedido pontual no chat; conta vai com `contas: [n]` no corpo do pedido
107
+ e o Studio confere depois da resposta, mesmo que a IA não peça); **Ignorar** (`decisoes` no relatório). O que não
108
+ dá para conferir sozinho (aviso visual, figura, origem) sai do painel ao ir para o chat (`enviado`).
109
+ - Toda conferência das contas pelo chat grava o resultado no relatório (`recordMath`): conta corrigida sai do painel.
110
+ - **Conferir de novo** (`/api/conferencia/conferir`): contas (`checkMath` só auditando), números (`unsupportedNumbers`,
111
+ o núcleo do `checkNumbers`) e figuras (`uncoveredVisuals`) no deck atual; sem IA, confere o que não precisa dela.
112
+ - As pendências vão junto de cada pedido ao chat (`editDeck({ pending })`, bloco PENDÊNCIAS DA CONFERÊNCIA
113
+ AUTOMÁTICA); o ignorado não vai, nem quando a mensagem antiga dos avisos está na conversa. REFERENCIA atualizada.
114
+ Testes: `ai.test.js` (itens, ignorar, recordMath, Conferir de novo com e sem IA) e `studio-ai.test.js` (o painel
115
+ usado como a pessoa usaria: selo, Conferir de novo, Ignorar, Corrigir com IA numa conta e num slide da IA,
116
+ conferindo deck salvo, relatório e o que foi ao modelo; zero erros JS). Ícones Lucide novos: list-checks,
117
+ calculator, hash, image-off. Suíte completa: `npm test`, 1.116 testes, 1.087 aprovados, 29 condicionais pulados, zero falhas.
118
+ Falta: PR empilhado sobre o #201 (`claude/conferir-contas`), CI verde, merge.
119
+
120
+ ## Pedido da criação gravado — 22/10/2026 (branch `claude/pedido-da-criacao-0d34bc`, sobre `claude/conferir-contas`)
121
+
122
+ Origem: no deck da Mary dava para provar que ela anexou um PPTX (estava em `contexto/`), mas não o que ela pediu: o
123
+ briefing não ficava salvo e o serviço não loga pedidos.
124
+ Feito: `src/studio/generation-request.js` grava `.sagadeck/geracao.json` em arquivo próprio (não mexe no relatório
125
+ `avaliacao-geracao.json`): data, origem (`biblioteca`, `editor`, `chat`), o briefing exatamente como foi para a IA e
126
+ `briefingPadrao` (a pessoa não escreveu nada e foi o texto padrão da tela; a biblioteca manda `guide.padrao`, com
127
+ intenção, público, objetivo e roteiro), resposta à pergunta da IA, duração, slides, tema, estilo, direção, anexos
128
+ (nome, tipo, tamanho em bytes, caracteres lidos, caminho em `contexto/documentos/<hash>/`), Preferências que mudam a
129
+ geração (idioma, imagens, pesquisa, perguntar, autor), fontes da pesquisa, modelos e o endereço do provedor sem
130
+ usuário, senha nem parâmetros (nada de chave). Criar pelo chat com documento anexado reescrevendo a maior parte do
131
+ deck grava o mesmo arquivo (origem `chat`); o pedido anterior vai para `anteriores` (10 últimos). Duplicar já copia a
132
+ pasta inteira; o pacote `.sagadeck` agora leva `.sagadeck/geracao.json`.
133
+ Testes: `storage.test.js` (biblioteca com anexo; segredos e `anteriores`), `library-ui.test.js` (pedido guiado
134
+ digitado; só com anexo grava o texto padrão marcado, duplicar e o pacote levam o arquivo, zero erros JS),
135
+ `studio-ai.test.js` (Deck com IA do editor e criação pelo chat com docx). Conferido que falham sem a gravação.
136
+ Falta: PR com CI verde e merge (depois do PR #201, que é a base).
137
+
138
+ ## Modelo para conferir — 22/10/2026 (branch `claude/modelo-por-etapa-d74f41`, parte de `claude/conferir-contas`)
139
+
140
+ Origem: no ensaio real da conferência das contas, o modelo de texto (deepseek flash) levou 5 a 12 min e uma rodada
141
+ estourou tokens. Um modelo de raciocínio mais forte só nas conferências dá precisão sem encarecer a escrita.
142
+ Feito:
143
+ - `~/.sagadeck/ia.json` ganhou o papel opcional `models.check` (`ROLES` em `src/ai/ia-config.js`); `llmConfig()` dá
144
+ `checkModel` (variável `SAGADECK_CHECK_MODEL`, senão `models.check`, senão o de texto: nada muda para quem não
145
+ configurar). O apelido `"check"` resolve para ele em `resolveModel`, como `"vision"`.
146
+ - Usam `model: "check"`: a conferência das contas (`auditBatch` em `math-check.js`), a leitura crítica
147
+ (`critique.js`) e a confirmação dos achados da revisão visual (`quality.js`; se o modelo de conferir não aceitar
148
+ imagem, a chamada cai no de visão pelo caminho que já existia). A correção que a conferência pede continua no de
149
+ texto (é escrita). A checagem de números (`checkNumbers`) não tem chamada de conferência: acha os números no código
150
+ e pede a correção à escrita, então não mudou.
151
+ - Configurar IA: campo "Modelo para conferir" (largura inteira, com a linha "um modelo de raciocínio mais forte só
152
+ onde a conta precisa estar certa"). Os campos de modelo continuam texto livre, sem lista do provedor (nenhum tem).
153
+ - `ia-check`: recurso `conferencia` (CLI `--so=conferencia`, MCP, `/api/ia/check`): quando o modelo de conferir é
154
+ outro que o de texto, uma conta com resposta conhecida, com raciocínio e 4000 tokens; senão, `SEM CONFIG`.
155
+ Testes: `ai.test.js` (contas, leitura crítica e confirmação vão ao de conferir; a correção e a revisão ao de texto;
156
+ sem configurar, tudo ao de texto; falha sem a mudança), `ia-check.test.js`, `library-ui.test.js` (tela grava
157
+ `models.check` no ia.json, reabre mostrando, zero erros JS).
158
+
159
+ ## Conferência das contas — 22/10/2026 (branch `claude/conferir-contas`, worktree `../sagadeck-conferir-contas`)
160
+
161
+ Origem: deck de aula criado na Oracle (Hidráulica, Aula 5, conta da Mary) saiu com "L₁ ≈ 55 m" num exercício cuja
162
+ resposta o material não trazia; a própria conta escrita no slide dá ≈ 273 m (folga 2,73 m ÷ perda 0,01 m/m). O
163
+ gráfico do slide seguinte nascia desse número e comparava grandezas diferentes. Nenhuma checagem pegou:
164
+ - `unsupportedNumbers` ignorava inteiro de 2 dígitos ("55") e partia o decimal do LaTeX ("9{,}45" → "9", "45");
165
+ - a revisão visual (sem raciocínio) não refaz conta; dois avisos dela eram falsos (slide 11 se contradizia; slide 22
166
+ dizia que a barra de 120 era menor que a de 12, mas o gráfico renderiza certo, conferido em foto);
167
+ - os 24 avisos ficavam só em `.sagadeck/avaliacao-geracao.json`: o Studio nunca mostrava (ninguém via).
168
+ Feito:
169
+ - Filtro: resultado depois de ≈/\approx/"cerca de" é conferido mesmo pequeno; `{,}` do LaTeX vira um número só.
170
+ - `src/ai/math-check.js`: etapa "Conferindo as contas" na geração (depois da checagem de números) e no chat. A IA
171
+ escreve cada resultado como fórmula a partir dos dados (sem usar o número do slide); o código calcula com o
172
+ compilador do `calc` (`src/runtime/formula.js`, sem eval) e compara (casas do slide ou 3%). O que não bate volta
173
+ para a IA corrigir, junto com os slides que citam o número; confere de novo; o que sobrar vira aviso.
174
+ - Chat: a IA pede a conferência com `contas: [n]` ou `contas: true` (decide pelo prompt, seção CONFERIR AS
175
+ CONTAS); edição que muda números de slide com conta também é conferida.
176
+ - Relatório da criação grava `facts`, `math`, `coverage` e `avisado`; na primeira abertura os avisos viram mensagem
177
+ do chat (uma vez) e um toast.
178
+ - Prompt e REFERENCIA: resposta que o material não traz leva `provenance: derivado`; ordem de grandeza por um
179
+ segundo caminho; gráfico de balanço só compara grandezas da mesma natureza.
180
+ - Revisão: auditor descarta achado que se contradiz e desproporção que os valores do gráfico desmentem.
181
+ Testes: `ai.test.js` (filtro, aritmética, geração corrige e avisa, campo contas), `studio-ai.test.js` (avisos no
182
+ chat e correção pelo chat conferida no deck salvo, zero erros JS), `quality-direction.test.js`, e ao vivo
183
+ (`SAGADECK_LIVE=1`): o modelo real achou 600 s → 240 s e pediu `contas:` sozinho no chat.
184
+ Ensaios com o modelo real no deck da Mary (só em memória, nada gravado) mostraram mais três coisas, já tratadas:
185
+ número que está no material e não fecha (o 2,57 m da lista dela; a conta dá 1,29 m) vai à parte e segue o pedido
186
+ da pessoa ou a autoria (autor: fica no slide com "Confira" nas notes); a correção às vezes esquece o número velho
187
+ num passo (agora diz os campos onde ele aparece e tem segunda rodada); o deck inteiro de uma vez estourava tokens
188
+ (agora lotes de 4 slides, nova tentativa sem raciocínio, lote ruim vira "não conferido"). O 4º ensaio corrigiu
189
+ slides 21 (273 m), 22 (gráfico refeito: 945 cm disponíveis, sobra 273 cm), 26 (tabela) e 30 (resumo); achou também
190
+ erros que ninguém tinha visto (velocidades da tabela do slide 26). A correção pelo chat leva a conversa: "pode
191
+ corrigir o material" da pessoa vale sobre a regra da autoria.
192
+ Suíte completa: `npm test`, 1.108 testes, 1.079 aprovados, 29 condicionais pulados, zero falhas. Studio local na
193
+ 3517 rodando `c65772e` a partir desta worktree, para validação dela.
194
+ Falta (depois do ok dela): PR, CI verde, merge, deploy na Oracle (produção estava na 1.9.0) e, no deck da conta da
195
+ Mary, pedir à IA do sagadeck pelo chat que confira e corrija as contas (inclusive as do material: a aula é dela e
196
+ ela autorizou caprichar), corrija os avisos da criação e melhore a aula. A correção é da IA, não à mão.
197
+
198
+ ## UX para programação e APIs com cURL — 12/10/2026 (branch `codex/ux-dev-slides`, versão 1.10.0)
199
+
200
+ Pedido: reduzir dificuldade de uso, facilitar geração técnica, acrescentar recursos e dois temas bonitos com
201
+ animação; testar, PR, merge, publicar no npm e atualizar sagadeck-dev. Trabalho somente na pasta oficial,
202
+ sem worktrees, conforme AGENTS.md. Main começou limpa em `46e0afd`, com a CI dos quatro ambientes verde.
203
+
204
+ Diagnóstico: recursos técnicos existiam, mas começar dependia de descobrir layouts, escrever briefing do zero e
205
+ preencher campos estruturados. cURL era exibido sem realce de sintaxe; demos extensas não eram uma base curta.
206
+ Mudanças:
207
+ - Biblioteca com entradas Programação/APIs com cURL; Nova com IA oferece exemplos de pedidos, material técnico
208
+ colado, público/objetivo/roteiro opcionais, resumo, prévia do pedido e Ctrl+Enter. Intenção explícita orienta o
209
+ modelo pelo prompt, sem regras de decisão por regex; texto e estilo manual continuam prioritários.
210
+ - Bases sem IA (`src/studio/developer-starters.js`), cinco slides com exemplo consistente, guia, saída e terminal
211
+ de cenas. Criação pela biblioteca; a de APIs usa ENSAIO e funciona localmente sem credenciais externas.
212
+ - Início/Inserir › Código / cURL: conteúdo colado vira código, código guiado ou requisição de API. Parser de
213
+ argumentos sem shell e sem executar; opções não suportadas geram mensagem antes de inserir. Credenciais
214
+ reconhecidas viram referências a Segredos antes de gravar. Código de exibição é preservado literalmente.
215
+ - Etapas guiadas por seleção de linhas, no modal e em Formatar; linguagem inferida/selecionável; realce offline
216
+ novo de Bash/cURL, JSON e SQL. Anexos de código/configuração preservam espaços, indentação e linhas em branco.
217
+ - `terminal-pro` (grafite/menta, IDE) e `aurora-dev` (azul noite/lilás/ciano, painéis e luz suave): fontes embutidas,
218
+ contraste de texto/sintaxe, rede de capa que para fora dela e em movimento reduzido/exportação. Design usa o
219
+ mesmo caminho existente de tema salvo; nenhum deck pessoal modificado.
220
+
221
+ Regressões cobrem parser, segredos, código literal, etapas e arquivos gravados, prompts ao LLM, anexos técnicos,
222
+ criação sem IA, escolha dos temas por teclado, contraste, animação, movimento reduzido e exportação. Testes
223
+ direcionados de motor/fontes/guards: 85 aprovados; temas e geração passaram também no navegador.
224
+ Geração com IA real também aprovada: briefing técnico aplica Aurora Dev e mantém o cURL original copiável (62 s).
225
+ Revisão independente achou e reproduziu perdas de inteiros grandes ao proteger JSON e de variáveis na codificação
226
+ do formulário: proteção agora edita só spans sensíveis do texto. Interpolação contextual opt-in
227
+ (`request.bodyEncoding`/`urlEncoding`) mantém JSON/form/query corretos no envio; ensaio HTTP real confere `&`, aspas,
228
+ barras, Unicode, números grandes e máscara de respostas/gravações. URL com Segredo agora é enviada já resolvida.
229
+ Callbacks de upload/geração são invalidados ao trocar/cancelar modal; Tab fica no diálogo e Escape devolve foco.
230
+ Essas regressões falharam antes das correções e passaram depois. Suíte completa iniciada com as frentes estáveis.
231
+ Entrega final aguardando suíte completa e CI; publicação de `sagadeck@1.10.0` por release com trusted publishing.
232
+ Oracle: atualizar apenas `/opt/sagadeck-dev`/`sagadeck-dev.service` (3518), preservando produção. Reiniciar também
233
+ a instância local verificada na 3517 e conferir versão/recursos depois da atualização.
234
+ Retomada em 13/10 após limite da sessão. Suíte inicial: 1.084 testes, 1.054 aprovados, 27 condicionais pulados e
235
+ 3 falhas (uma de Python ausente no PATH, uma de rótulo e a contagem do teste pai). Python passou isolado com o
236
+ runtime disponível no PATH; a guarda de palavras grudadas agora reconhece o nome técnico cURL sem enfraquecer
237
+ os demais rótulos. A revisão final também cobre execução pelo navegador preservando corpo JSON literal e comandos
238
+ equivalentes copiáveis com segredos em JSON/form/query. Suíte final concluída: `npm test`, 1.093 testes,
239
+ 1.066 aprovados, 27 condicionais pulados, zero falhas (24 min). Geradores de cURL/JavaScript/Python também
240
+ enviaram pedidos reais ao ensaio HTTP. Preview e Formatar mantêm JSON literal; respostas/gravações não permitem
241
+ recuperar segredos mesmo em logs com JSON aninhado. Instância local reiniciada na 3517, versão 1.10.0, com os novos
242
+ módulos/CSS respondendo 200. PR #197 publicado; os quatro checks originais Ubuntu/Windows, Node 22/24, passaram.
243
+ Por orientação posterior do usuário, o suporte passa a Node 24+: engines, instruções de instalação e matriz da
244
+ CI atualizados, sem mudança no código já aprovado. YAML e metadados conferidos; a nova CI exige Ubuntu e Windows
245
+ com Node 24 antes de merge/release. DEV da Oracle recebeu `135cfd2`, com versão 1.10.0 e ambos os temas disponíveis;
246
+ produção preservada. A publicação npm ainda aguarda merge e CI do commit final.
247
+ PR #197 integrado em `03f9ff4`; local na 3517 e DEV na 3518 reiniciados com esse commit e versão 1.10.0.
248
+ Os dois checks do PR passaram, mas a nova rodada da main encontrou uma corrida no teste de Formatar: o helper
249
+ confirmava a gravação no servidor antes de o formulário do novo slide terminar de renderizar, lendo o corpo
250
+ do slide anterior. Publicação npm suspensa até corrigir e validar essa sincronização. Correção na branch
251
+ `codex/ux-dev-format-sync`; nenhuma mudança no conteúdo das apresentações nem no código da aplicação.
252
+ Atrasar `api/render-slide` em 400 ms reproduziu exatamente a falha da Ubuntu. O helper agora aguarda a
253
+ identidade do formulário pelo campo Título, além da gravação; a mesma regressão passou após o ajuste.
254
+ Seis testes dirigidos aprovados, zero erros JavaScript e corpos JSON/form conferidos também no arquivo salvo.
255
+ Suíte completa após o ajuste: `npm test`, 1.093 testes, 1.066 aprovados, 27 condicionais pulados e zero falhas
256
+ (30 min). A falha da main ficou restrita a essa sincronização; Windows passou. Correção pronta para commit/PR
257
+ e checks Ubuntu/Windows Node 24 antes de integrar e publicar a versão 1.10.0.
258
+
259
+ ## Assistente em prévia de modelo na Oracle — 12/10/2026
260
+
261
+ O erro `APP_UNKNOWN · a4670ccb` da produção era `path.dirname(null)` no preparo dos anexos: modelos abertos
262
+ pela vitrine ainda não têm arquivo. O pedido parava antes de chegar ao modelo. Agora o chat só prepara documentos
263
+ em uma pasta existente; documento binário, imagem gerada e edição materializam a cópia com os helpers da biblioteca.
264
+ Conversa simples continua sem criar arquivo. A aba do servidor e o endereço do editor passam a usar essa mesma
265
+ cópia, evitando edição perdida ou segunda cópia no pedido seguinte. Modelo de fábrica e outras pessoas preservados.
266
+ Regressão em `test/studio-ai-preview.test.js`: falhou antes com o erro exato; cobre conversa, edição salva,
267
+ recarregamento no navegador, isolamento por usuário e documento inventariado na pasta pessoal.
268
+ Imagem gerada também é conferida no arquivo e na pasta pessoal. Texto e visão reais passaram nos dois serviços.
269
+ A CI da main apresentou timeout no teclado ao mudar o título logo após abrir o editor no Windows 24; o teste da
270
+ biblioteca agora espera a página terminar de carregar antes de editar, mantendo a conferência do arquivo salvo.
271
+ Validação: npm test com 1.034 testes, 1.008 aprovados, 26 condicionais pulados, zero falhas; quatro regressões novas
272
+ passaram na suíte. O teste da biblioteca com a espera de carregamento passou também isolado (13 testes).
273
+ Entrega: commit da correção para os dois serviços da Oracle após validação local; merge do PR somente com os quatro
274
+ checks verdes (Ubuntu/Windows, Node 22/24). Não há mudança de dependências nem publicação de versão no npm.
275
+ PR #196 publicado. Oracle dev (3518) e produção (3517) receberam o commit `e32a3c1` e reiniciaram; nos dois,
276
+ o pedido real em uma prévia voltou com `mode: llm`, conversa, sem diagnóstico de erro e sem criar cópia.
277
+ Bibliotecas pessoais não foram alteradas. A CI do PR continua sendo acompanhada para concluir o merge.
278
+ Revisão adicional reproduziu perda ao recarregar quando o patch só mudava campos do deck (tema, contexto…) ou
279
+ excluía slides: a lista de slides alterados era vazia e a cópia não nascia. A materialização agora vale para toda
280
+ ação do modelo, preservando conversa e alternativas em prévia. Regressão confere tema salvo, exclusão e demais
281
+ slides preservados; falhou antes da correção.
282
+ Suíte completa após esse ajuste: 1.035 testes, 1.009 aprovados, 26 condicionais pulados e zero falhas.
283
+ Os cinco testes de prévia passaram; nova CI será exigida para o commit final antes do merge do PR #196.
284
+ Oracle dev e produção receberam também `333857f`: conversa real e mudança de tema pelo modelo funcionaram;
285
+ o tema permaneceu ao reabrir o arquivo pelas APIs nativas. Apresentações sintéticas removidas pela biblioteca.
286
+ A CI aprovou Ubuntu 22/24 e Windows 22. Windows 24 teve timeout na galeria; o teste isolado passou (3/3) e a
287
+ reexecução aprovou o carrossel, mas encontrou `ERR_NO_BUFFER_SPACE` durante exportação. Isso indica pressão de
288
+ recursos de rede no runner; a faixa TCP dinâmica agora é ampliada somente nas máquinas descartáveis da CI,
289
+ com diagnóstico de estados TCP em falhas. Testes e exigência de zero erros de navegador preservados.
290
+ Código da aplicação permanece o mesmo da suíte local completa aprovada (1.009/26/0); ajuste de CI validado como
291
+ YAML, e os quatro ambientes serão novamente conferidos antes do merge.
292
+
293
+ ## Sobre legível no tema escuro — 12/10/2026 (branch `sobre-tema-escuro`)
294
+
295
+ Narumi (com print): no Windows e no dev da Oracle o Sobre "não abre direito", com texto apagado. Causa: o CSS do
296
+ `about.js` pegava o fundo de `--panel`/`--bg`, que nenhuma página define (caía no branco), e o texto de `--text`,
297
+ que no tema escuro é claro, o que dava contraste 1,16. Agora fundo, borda e botão vêm de `--chrome`, `--ui-line` e
298
+ `--brand-fill`, que o editor (style.css/studio-next.css) e a biblioteca (library.css) definem nos dois temas. Teste
299
+ novo em `test/sobre.test.js`: contraste WCAG mínimo de 4,5 do texto contra o fundo da janela, nos temas claro e
300
+ escuro, no editor e na biblioteca. Ele falha com o CSS antigo.
301
+
302
+ ## Ajuda › Sobre o SagaDeck — 12/10/2026 (branch `ajuda-sobre`)
303
+
304
+ Narumi: "insira um help com about no menu onde eu posso ver a versão". A aba **Ajuda** fecha a faixa do editor
305
+ (depois de Avançado, como no PowerPoint) com Sobre o SagaDeck, O que mudou (CHANGELOG) e Demos. O Sobre
306
+ (`src/studio/public/about.js`, `window.SagaAbout`; qualquer elemento com `data-about` abre) mostra a versão em
307
+ destaque, commit, Node e sistema (novos em `/api/instance`), desde quando está no ar, a biblioteca (no multiusuário,
308
+ só que é do servidor) e se a IA está configurada, com Copiar informações para suporte. Na biblioteca, um botão com o
309
+ ícone de informação no alto. Achados de passagem: o `dialog` nativo abria colado no canto (uma regra global zerava
310
+ a margem; o Sobre põe `margin:auto`) e botão da faixa que é link (`a.rbtn`) saía sublinhado. Teste:
311
+ `test/sobre.test.js`; a ordem da faixa em `studio.test.js`.
312
+
11
313
  ## `sagadeck ia-check`: o que de IA funciona, sem tela — 12/10/2026 (branch `ia-check`)
12
314
 
13
315
  Narumi: "o sagadeck está preparado para ser testado por um agente de IA (tipo o Copilot) sem o front-end?
@@ -15,7 +15,7 @@ Mídia paga não é proibida por padrão. Quando for apropriada, proponha seu us
15
15
  ```yaml
16
16
  title: Nome da palestra # obrigatório (vira rodapé e título da janela)
17
17
  author: Seu Nome · Cargo
18
- theme: sinal # sinal | editorial | noite | bauhaus | terminal | jornal | rabisco | oceano | pop | aurora | prata | aluminio | arcade | relevo | musgo | wine | caderno | lousa | cartaz | infografico (ou customizado, ver fim)
18
+ theme: sinal # sinal | editorial | noite | bauhaus | terminal | terminal-pro | jornal | rabisco | oceano | pop | aurora | aurora-dev | prata | aluminio | arcade | relevo | musgo | wine | caderno | lousa | cartaz | infografico (ou customizado, ver fim)
19
19
  palette: floresta # opcional: só as cores, vale em qualquer tema (ver "Temas e paletas"); sem ela, as cores do tema
20
20
  duration: 50 # minutos — o modo apresentador mostra se você está adiantado/atrasado
21
21
  event: Summit de Dados 2026 # opcional — para {evento} no rodapé/cabeçalho
@@ -132,7 +132,7 @@ Tabela em markdown no meio de um texto (`problem`, `body`, `text`, passo do `sol
132
132
 
133
133
  ### Cenas interativas para ensinar
134
134
 
135
- `codewalk` mantém o código estável e revela a explicação, o destaque de linhas e uma saída esperada por etapa. O código e os comandos cURL são texto; não há execução. No Studio, a linguagem é inferida pela extensão do arquivo e pode ser escolhida no menu: Python (`.py`), Java (`.java`), JavaScript (`.js`, `.jsx`, `.mjs`, `.cjs`), TypeScript (`.ts`, `.tsx`, `.mts`, `.cts`) ou C# (`.cs`). Node.js é um runtime de JavaScript, não uma linguagem separada; arquivos Node usam a opção JavaScript. A apresentação aplica realce sintático a essas cinco linguagens sem depender de serviços externos. Use as setas da apresentação ou os botões numerados. Depois da última etapa, a seta avança ao slide seguinte. As etapas também aparecem corretamente na prévia do apresentador e são restauradas pelo endereço da apresentação.
135
+ `codewalk` mantém o código estável e revela a explicação, o destaque de linhas e uma saída esperada por etapa. O código e os comandos cURL são texto; não há execução. No Studio, a linguagem é inferida pela extensão do arquivo e pode ser escolhida no menu: Python, Java, JavaScript, TypeScript, C#, Bash/cURL, JSON ou SQL. Node.js é um runtime de JavaScript, não uma linguagem separada; arquivos Node usam a opção JavaScript. A apresentação aplica realce sintático a essas oito linguagens sem depender de serviços externos. Use as setas da apresentação ou os botões numerados. Depois da última etapa, a seta avança ao slide seguinte. As etapas também aparecem corretamente na prévia do apresentador e são restauradas pelo endereço da apresentação.
136
136
 
137
137
  ```yaml
138
138
  - layout: codewalk
@@ -172,6 +172,46 @@ O cabeçalho do deck aceita `fit: { minCodePt, minTextPt, wrapCode }`: até onde
172
172
 
173
173
  O cabeçalho do deck aceita `motion: none | subtle | expressive` (padrão `subtle`; no Studio, menu **Apresentar ▾ › Animações**: Sem animação, Suaves, Expressivas). A preferência do sistema por movimento reduzido tem prioridade. A intensidade muda a animação; os controles e revelações continuam funcionando.
174
174
 
175
+ ## Criar apresentações de programação e APIs no Studio
176
+
177
+ Na biblioteca, **Programação** e **APIs com cURL** abrem a criação com IA já orientada ao assunto. A pessoa pode
178
+ escrever livremente, usar um exemplo de pedido, colar código/comando/resposta ou anexar arquivos técnicos. Público,
179
+ objetivo e roteiro são opcionais. A prévia mostra o pedido completo antes de gerar; Ctrl+Enter inicia a geração.
180
+ O tema sugerido é `terminal-pro` para programação e `aurora-dev` para APIs; uma escolha manual de estilo prevalece.
181
+ Essas escolhas orientam o modelo pelo prompt, sem impor uma sequência fixa de layouts.
182
+
183
+ **Começar com um exemplo, sem IA** cria uma base editável de cinco slides na biblioteca, com exemplo consistente,
184
+ código guiado, saída e capa com terminal animado. Programação inclui um diagrama do fluxo. APIs inclui uma chamada
185
+ POST ao ambiente `ensaio`, que funciona no Studio local sem configurar credenciais. No servidor multiusuário,
186
+ chamadas de API seguem o modo de gravação existente. Cada uso cria uma apresentação independente.
187
+
188
+ **Inserir › Código / cURL** aceita conteúdo colado e oferece código para mostrar, código guiado por etapas ou
189
+ requisição de API a partir de cURL. O importador lê os argumentos sem abrir um shell e sem executar a chamada.
190
+ Nos guias, selecionar linhas e adicionar uma etapa cria o destaque, com explicação e saída ilustrativa editáveis;
191
+ o painel Formatar também oferece essa ação. Código de exibição e guia não são executados.
192
+
193
+ A importação de cURL aceita método/URL, cabeçalhos, corpo literal/JSON, consulta com `-G` e `--data-urlencode`,
194
+ aspas e continuação de linha. Credenciais reconhecidas em cabeçalhos, consulta ou corpo são substituídas por
195
+ `{{secret.nome}}`; a prévia informa os nomes para cadastrar em Ambientes. Os demais bytes do JSON, inclusive números
196
+ grandes e formatação, são preservados. Variáveis existentes `{{nome}}` continuam referenciadas. Opções sem equivalente
197
+ no executor, como `-L`, `-k`, multipart `-F`, corpo vindo de arquivo `@` e substituição de shell, geram um erro claro;
198
+ para apenas exibir o comando completo, escolha Código no slide.
199
+
200
+ O importador acrescenta `request.bodyEncoding: json | urlencoded` e `request.urlEncoding: query` quando apropriado.
201
+ Esses campos preservam o escape dos valores interpolados no corpo e nos parâmetros da URL, primeiro com variáveis
202
+ e depois com Segredos, inclusive aspas, Unicode e `&`. O restante do corpo literal permanece intacto. Não é preciso
203
+ configurá-los no formulário. Pedidos existentes sem esses campos mantêm a interpolação anterior.
204
+ Os exemplos copiáveis de cURL, JavaScript e Python respeitam esses mesmos escapes. O cURL simples continua curto;
205
+ quando um Segredo precisa ser escapado em JSON/form/query, o exemplo Bash inclui um pequeno helper Node.js e indica
206
+ essa dependência no próprio comando. Literais como `$HOME` continuam literais quando vieram assim no cURL original.
207
+
208
+ Além de Python, Java, JavaScript, TypeScript e C#, o realce offline aceita **Bash** (`.sh`, `.bash`; aliases `shell`,
209
+ `sh`, `curl`), **JSON** (`.json`, `.jsonc`) e **SQL** (`.sql`). Bash destaca comandos, opções e variáveis; JSON,
210
+ chaves e valores; SQL, palavras-chave sem exigir maiúsculas. O conteúdo continua copiável, com indentação e linhas
211
+ preservadas. Anexos de código (`js`, `ts`, `py`, `sh`, `http`, `sql`, `go`, `rs`, `java`, `cs` e outros) entram como
212
+ material de contexto sem remover espaços ou linhas em branco. Saídas simuladas devem ser identificadas como exemplos;
213
+ nunca afirme execução sem evidência nem invente endpoints ou resultados reais.
214
+
175
215
  ## Screenshots com destaques no Studio
176
216
 
177
217
  Em **Início → Screenshot**, cole (Ctrl+V), arraste ou escolha uma imagem PNG, JPEG ou WebP de até 8 MB.
@@ -528,7 +568,7 @@ aparecem (`showValues: true` força os valores).
528
568
  **SVG próprio**: `{ svg: "<svg viewBox='0 0 100 100'>…</svg>" }` — use `style="fill:var(--fg)"`, `var(--hi)`, `var(--em)` para seguir o tema.
529
569
  **Imagem**: `{ image: foto.jpg, fit: cover }` (caminho relativo ao YAML; é embutida no HTML). Sem `fit`, a imagem preenche a caixa, mas cabe inteira (`contain`) quando o corte passaria de 20% (gráfico com eixo e legenda na borda, esquema largo numa coluna alta); solta no fluxo (num `add`) e sem altura, não passa de 420 px. Para foto que pode ser cortada, `fit: cover`; para gráfico, `fit: contain`.
530
570
  **Imagem gerada por IA**: `{ image_prompt: "descrição visual, em inglês", fit: cover }` (sai sem texto: rótulos, números e títulos vão no slide; se a ilustração precisa de rótulos dentro dela, diga quais no prompt, em português e entre aspas: `with labels "Divisor de água", "Rio"`) — `sagadeck imagens deck.yaml` gera o arquivo em `imagens/` com o modelo de imagem e troca por `image:`.
531
- **Redesenhar uma figura do deck** (xerox, escaneada, borrada): `{ image_prompt: "Clean up and redraw THIS EXACT figure… (o que ela mostra, as cores)", image_ref: imagens/original/mapa.png, fit: contain }` — o modelo de imagem recebe a figura como base e devolve o redesenho; se não sair, fica a figura de base. Depois do redesenho, o elemento guarda a figura de base em `original` (ex.: `{ image: imagens/ia-1a2b.png, original: contexto/visuais/…/fig.png, fit: contain }`). Figura de documento anexado (PDF) traz no inventário `sourcePx` (tamanho nativo da imagem): esquema de caixas e setas borrado vira `diagram` nativo fiel; gráfico com os valores no paper vira `chart` nativo com os números exatos; gráfico sem os dados à mão e ilustração podem ser redesenhados assim; mapa e foto ficam. Reconstrução nativa de figura do documento leva no slide `sourceFigure: contexto/visuais/…/fig.png`. **Origem do conteúdo** (deck com material anexado): cada slide de conteúdo leva `provenance: material` (o que afirma está no material), `provenance: derivado` (reorganização, cálculo ou gráfico feito a partir dos números do material) ou `provenance: proprio` (inclusão da IA: contexto, analogia, exemplo, crítica), com `provenanceNote` curta quando não for `material`; o Studio mostra um selo na miniatura, a apresentação não. O deck grava `context.autoria`: `autor` (a pessoa apresenta o próprio trabalho: fiel ao material, crítica e perguntas prováveis nas notes) ou `livre` (aula, resenha, journal club, divulgação, tema geral: conteúdo próprio liberado, marcado). A **leitura crítica** do material (inconsistências, achados escondidos, perguntas prováveis, limitações, slide que representa mal o material, cada item com trecho literal conferido) fica em `.sagadeck/leitura-critica.json` e acompanha os pedidos ao chat. **Voltar ao original** ("mantenha a figura original", "volte para o gráfico do paper"): o visual do slide vira `figure: { image: <sourceFigure ou original>, fit: contain }`, sem mexer no texto. Números que o paper só dá no texto ou em tabela podem virar `chart` criado pela IA, com os valores exatos e `source` dizendo de onde vieram. Equação com `latex` no inventário vai como fórmula nativa (`math`, `equations`), nunca como o recorte.
571
+ **Redesenhar uma figura do deck** (xerox, escaneada, borrada): `{ image_prompt: "Clean up and redraw THIS EXACT figure… (o que ela mostra, as cores)", image_ref: imagens/original/mapa.png, fit: contain }` — o modelo de imagem recebe a figura como base e devolve o redesenho; se não sair, fica a figura de base. Depois do redesenho, o elemento guarda a figura de base em `original` (ex.: `{ image: imagens/ia-1a2b.png, original: contexto/visuais/…/fig.png, fit: contain }`). Figura de documento anexado (PDF) traz no inventário `sourcePx` (tamanho nativo da imagem): esquema de caixas e setas borrado vira `diagram` nativo fiel; gráfico com os valores no paper vira `chart` nativo com os números exatos; gráfico sem os dados à mão e ilustração podem ser redesenhados assim; mapa e foto ficam. Reconstrução nativa de figura do documento leva no slide `sourceFigure: contexto/visuais/…/fig.png`. **Origem do conteúdo** (deck com material anexado): cada slide de conteúdo leva `provenance: material` (o que afirma está no material), `provenance: derivado` (reorganização, cálculo ou gráfico feito a partir dos números do material) ou `provenance: proprio` (inclusão da IA: contexto, analogia, exemplo, crítica), com `provenanceNote` curta quando não for `material`; o Studio mostra um selo na miniatura, a apresentação não. O deck grava `context.autoria`: `autor` (a pessoa apresenta o próprio trabalho: fiel ao material, crítica e perguntas prováveis nas notes) ou `livre` (aula, resenha, journal club, divulgação, tema geral: conteúdo próprio liberado, marcado). A **leitura crítica** do material (inconsistências, inclusive conta do material que não fecha com os próprios dados, achados escondidos, perguntas prováveis, limitações, slide que representa mal o material, cada item com trecho literal conferido) fica em `.sagadeck/leitura-critica.json` e acompanha os pedidos ao chat. **Voltar ao original** ("mantenha a figura original", "volte para o gráfico do paper"): o visual do slide vira `figure: { image: <sourceFigure ou original>, fit: contain }`, sem mexer no texto. Números que o paper só dá no texto ou em tabela podem virar `chart` criado pela IA, com os valores exatos e `source` dizendo de onde vieram. Equação com `latex` no inventário vai como fórmula nativa (`math`, `equations`), nunca como o recorte.
532
572
 
533
573
  ## Notas / roteiro (`notes`)
534
574
 
@@ -547,6 +587,12 @@ Linhas que começam com PALAVRAS EM MAIÚSCULAS seguidas de `:` viram etiquetas
547
587
 
548
588
  ## Temas e paletas
549
589
 
590
+ Temas de desenvolvimento: `terminal-pro` usa grafite, menta e azul, títulos alinhados à esquerda, rótulos
591
+ monoespaçados e janelas de código; `aurora-dev` usa azul noite, lilás e ciano, luz suave e painéis arredondados.
592
+ Ambos usam Space Grotesk e IBM Plex Mono embutidas, código sem ligaduras e cores de sintaxe com contraste de leitura.
593
+ A rede ambiente da capa anima enquanto ela está ativa; `ambient: false` remove o efeito. Movimento reduzido,
594
+ `motion: none` e exportação deixam a rede estática, com código e explicações legíveis.
595
+
550
596
  Como no PowerPoint, são duas escolhas independentes:
551
597
 
552
598
  - **Tema** (`theme`): fontes, raio das bordas, textura e uma **pele** própria que rearruma capa, seção e encerramento, muda o jeito dos slides de conteúdo (título, cartões, marcadores da lista, citação, número grande, frase) e põe ornamentos (`sinal`: faixa zebrada e selo no chapéu; `editorial`: fios e capa centralizada; `noite`: moldura fina; `bauhaus`: círculo, quadrado e triângulo; `terminal`: janela com barra e prompt; `jornal`: fios de jornal e manchete sublinhada; `rabisco`: fitas adesivas e títulos inclinados; `oceano`: ondas e chapéu em pílula; `pop`: adesivos e sombra chapada; `aurora`: brilhos e traço em gradiente; `prata`: limpo e centralizado; `relevo`: ficção científica sóbria (sala de controle de filme, sem néon): grafite profundo, curvas de nível ao fundo, cantoneiras de mira, título leve embaixo à esquerda, rótulos técnicos em monoespaçada; combina com ilustração 3D realista (terreno, cidade, água) e gráfico 3D (`science` com superfície); `arcade`: videogame e fliperama, tela de tubo com linhas de varredura, neon, título em pixel no meio e chão de tijolos de jogo de plataforma; `aluminio`: prata metálico de lançamento de aparelho premium, título cromado embaixo à esquerda e um disco de metal polido; `wine`: o `musgo` em vinho (mesmo arranjo, fontes, faixa e rede na capa): fundo vinho quase preto, vermelho-rosado e rosé, com o vermelho forte só no detalhe; `caderno`: visual thinking em papel claro — título em letra de mão alta (Amatic SC) com traço de lápis, chapéu coral em serifada (Gelasio), frase em lilás, rabiscos de ícones em pastel nos cantos (lupa, ampulheta, engrenagem, lápis, chave, lâmpada); `lousa`: quadro-negro verde com giz — título em giz amarelo (Cabin Sketch) com traço laranja, linha de giz sob o título, poeira e marcas de giz apagado, lâmpada e lápis de giz na capa; `cartaz`: cartaz de protesto em papel cinza com grão — condensada pesada (Bebas Neue) em faixa vermelha torta, chapéu como etiqueta amarela, moldura preta grossa na capa, número da seção num disco amarelo; `infografico`: dados chapados — capa azul com chão verde e nuvem, títulos em maiúsculas, chapéu numa tarja verde, números enormes em condensada; `musgo`: laboratório noturno de bom gosto (verde-musgo quase preto, âmbar e sálvia, serifada Fraunces com o destaque do título em âmbar itálico, rótulos em IBM Plex Mono com fio âmbar, texto em Space Grotesk): grade de pontos que some nas bordas e luz âmbar na capa, seção como separador com o número entre fios na linha do chapéu e o título grande embaixo, e a faixa que corre no pé da capa com os títulos das seções (`ticker`); combina com o terminal de cenas (`motion: {type: console}`) na figura da capa ou num `canvas`; `manual` e `manual-noite`: documentação técnica, sem ornamento, código e texto corrido legíveis — o par claro/escuro do mesmo arranjo, para material de consulta, tutorial e apostila: `manual` imprime bem, `manual-noite` descansa a vista). Nos slides de conteúdo: `sinal` barra de aviso e placas; `editorial` fios finos e citação centralizada; `noite` tudo centralizado e cartões vazados; `bauhaus` faixas de cor primária e círculos; `terminal` título como comando e cartões-janela; `jornal` fios duplos e colunas; `oceano` cartões flutuando e balões; `pop` contorno grosso e sombra dura; `prata` centralizado e sem caixa; `aluminio` cartões de alumínio com chanfro de luz; `relevo` painéis de vidro fosco com traço gelo; `arcade` cartões de 8 bits com borda de pixel e sombra dura; `rabisco` tracejados e números circulados; `aurora` vidro com brilho; `caderno` cartões brancos com moldura grossa pastel (menta, lilás, amarelo, coral) e marcador amarelo contornado; `lousa` cartões contornados a giz com borda torta e marcadores em pingo de giz; `cartaz` cartões brancos girados como fotos coladas, números de lista em etiqueta e destaque em vermelho; `infografico` cartões com a faixa da cor do grupo, números em cartões coloridos e números de lista em círculos coloridos; `musgo`/`wine` cartões vazados que sobem no mouse, números em monoespaçada âmbar, marcador em losango, código em janela com três bolinhas e botões âmbar. Trocar o tema já muda o arranjo: não reescreva slides só para "combinar" com o tema.
@@ -723,7 +769,26 @@ Tabela é tabela, nunca imagem: dados de um livro ou de um PowerPoint que vieram
723
769
 
724
770
  ## Aula: exercício resolvido, calculadora ao vivo, algoritmo animado (`solution`, `calc`, `algo`)
725
771
 
726
- **`solution` — exercício resolvido passo a passo.** À esquerda, `problem` (enunciado), `givens` (dados: `{symbol, value, unit, label}` ou `{latex, label}`; vírgula decimal pode) e `find` (o que se pede, LaTeX). À direita, a conta: o primeiro quadro pergunta `prompt` (padrão "Por onde você começaria?"); cada clique revela o próximo `steps: [{text, latex, note}]` (os anteriores ficam compactos); o último mostra `answer: {latex, text, label}` em destaque. Mantenha cada passo curto (uma ideia, uma linha de conta); de 3 a 6 passos. Use para qualquer matéria com conta: física, engenharia, finanças, estatística.
772
+ **`solution` — exercício resolvido passo a passo.** À esquerda, `problem` (enunciado), `givens` (dados: `{symbol, value, unit, label}` ou `{latex, label}`; vírgula decimal pode) e `find` (o que se pede, LaTeX). À direita, a conta: o primeiro quadro pergunta `prompt` (padrão "Por onde você começaria?"); cada clique revela o próximo `steps: [{text, latex, note}]` (os anteriores ficam compactos); o último mostra `answer: {latex, text, label}` em destaque. Mantenha cada passo curto (uma ideia, uma linha de conta); de 3 a 6 passos. Use para qualquer matéria com conta: física, engenharia, finanças, estatística. Resposta que o material não traz é cálculo da IA: o slide leva `provenance: derivado` com `provenanceNote` ("resposta calculada pela IA"). Toda conta do deck passa pela **conferência das contas**: a IA escreve cada resultado como fórmula a partir dos dados e o sagadeck calcula (o mesmo compilador do `calc`, convertendo as unidades: L/s e m³/s, cm e m) e compara com o slide (vale a conta nos números dados ou com a conversão: só é divergência o que não bate de jeito nenhum); o que não bate volta para correção e o que sobrar vira aviso. No chat, `contas: [n]` (ou `contas: true`) pede essa conferência. O que as checagens automáticas deixam pendente (contas que não batem, contas do material que não fecham, números sem base no material, avisos da revisão visual, figuras do material sem slide, slides `derivado`/`proprio`) fica no painel **Revisar › Conferência** do Studio, por slide, com Corrigir com IA e Ignorar; a lista do que está pendente acompanha os pedidos ao chat (PENDÊNCIAS DA CONFERÊNCIA AUTOMÁTICA), e o que a pessoa ignorou sai dela.
773
+
774
+ **Contas calculadas pelo sagadeck (`fn`) — prefira sempre que o exercício tem conta.** Não escreva o resultado à mão: escreva a fórmula e deixe o sagadeck calcular. Cada dado com `symbol` e `value` numérico vira uma variável (o nome vem do símbolo: `L_1` → `L1`, `\rho` → `rho`, `h_f` → `hf`; ou dê `name`). Cada passo pode ter `fn` (fórmula em texto, as mesmas regras do `calc`: `C*(1+i)^n`, `sqrt(2*g*h)`, `(D/f)*(2*g/v^2)*hd`), `name` (para os passos seguintes usarem o resultado), `unit` e `decimals` (casas; sem ele, 4 algarismos). O valor entra no fim do LaTeX do passo (`latex: "L_1 = \frac{D}{f}\cdot\frac{2g}{v^2}\cdot h"` sai `… ≈ 272,9 m`), ou onde estiver `{{nome}}`; passo só com `fn` mostra `nome = valor`. `{{nome}}` vale também nos textos, na `answer` (`latex: "L_1 \approx {{L1}}\ \mathrm{m}"`, `text: "cabem uns {{L1:0}} m de tubo"`) e no enunciado; `{{expressão:casas}}` faz uma conta curta (`{{(M/C - 1)*100:0}}%`). Vírgula decimal e milhar saem sozinhos. Fórmula com erro ou letra sem valor aparece no slide como aviso, com o motivo. A resposta pode ter `fn` também. `interactive: true` põe um controle em cada dado: a pessoa muda um dado na apresentação e todos os passos e a resposta recalculam (`min`/`max`/`step` no dado ajustam o controle; sem eles, de um décimo a dez vezes o valor). Passo sem `fn` continua como sempre (fórmula escrita, sem conta). A conferência das contas só refaz o que foi escrito à mão.
775
+
776
+ ```yaml
777
+ - layout: solution
778
+ title: Até onde o sifão alcança?
779
+ givens:
780
+ - { symbol: D, value: "0,3", unit: m, label: diâmetro }
781
+ - { symbol: f, value: "0,026", label: fator de atrito }
782
+ - { symbol: g, value: "9,81", unit: m/s², label: gravidade }
783
+ - { symbol: v, value: "1,5", unit: m/s, label: velocidade }
784
+ - { symbol: h, value: "2,73", unit: m, label: carga disponível }
785
+ find: L_1
786
+ steps:
787
+ - { text: Perda por metro de tubo, latex: "J = \\frac{f}{D}\\cdot\\frac{v^2}{2g}", fn: "f/D*v^2/(2*g)", name: J, decimals: 4 }
788
+ - { text: Comprimento que a carga paga, latex: "L_1 = \\frac{h}{J}", fn: "h/J", name: L1, unit: m, decimals: 1 }
789
+ answer: { latex: "L_1 \\approx {{L1}}\\ \\mathrm{m}", text: "Cabem cerca de {{L1:0}} m de tubo." }
790
+ interactive: true
791
+ ```
727
792
 
728
793
  **`calc` — calculadora ao vivo.** `inputs: { nome: {label, value, min, max, step, unit, latex, decimals} }` viram controles deslizantes (`fixed: true` = constante, mostrada com `latex`). `outputs: [{name, label, fn, latex, unit, decimals}]` são calculados na ordem (um usa os anteriores e as entradas pelo nome, inclusive nomes longos como `nu`, `eps`); `fn` é fórmula em texto (as mesmas regras de `plot.functions`: `V*D/nu`, `0.25/(log10(eps/(3.7*D) + 5.74/Re^0.9))^2`; `log` e `log10` são base 10, `ln` é natural). Faixas: `of: Re, cases: [{below: 2300, text: Laminar, color: s3}, {below: 4000, text: Transição, color: em}, {text: Turbulento, color: hi}]` — mostra o selo da faixa; cada faixa pode ter a sua `fn` (f = 64/Re abaixo de 2300, outra acima). `scale: {min, max, log}` desenha a régua com as faixas e o ponteiro. Tudo recalcula enquanto a pessoa arrasta; PDF mostra os valores iniciais.
729
794
 
@@ -1181,6 +1246,9 @@ cada resultado sai assim que chega:
1181
1246
  aceita imagem falha, em vez de responder sem ver);
1182
1247
  - **imagem**: gera uma imagem pequena e confere que voltou PNG, JPEG, WebP ou GIF (grava o arquivo e diz onde);
1183
1248
  - **pesquisa**: o modelo de pesquisa precisa dizer a data de hoje;
1249
+ - **conferência**: quando há um **modelo para conferir** em Configurar IA (outro que o de texto; é o das contas, da
1250
+ leitura crítica e da confirmação da revisão visual), uma conta pequena com resposta conhecida, com raciocínio; sem
1251
+ ele, as conferências usam o modelo de texto e sai `SEM CONFIG`;
1184
1252
  - **vídeo**: sem `--video-real`, só confere o modelo no catálogo, de graça, e sai `SEM PROVA`; com `--video-real`,
1185
1253
  gera o clipe mais curto e leve que o modelo aceita, acompanha, baixa e confere o MP4 (cobrado; leva minutos).
1186
1254
 
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "sagadeck",
3
- "version": "1.9.0",
3
+ "version": "1.11.0",
4
4
  "description": "Gerador de apresentações: YAML -> HTML animado + PowerPoint editável, com temas e figuras geradas na hora.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "sagadeck": "bin/sagadeck.js"
8
8
  },
9
9
  "engines": {
10
- "node": ">=22.13.0"
10
+ "node": ">=24.0.0"
11
11
  },
12
12
  "license": "MIT",
13
13
  "homepage": "https://github.com/naruminho/sagadeck#readme",
@@ -29,7 +29,7 @@
29
29
  ],
30
30
  "dependencies": {
31
31
  "jszip": "^3.10.2",
32
- "katex": "^0.18.9",
32
+ "katex": "^0.19.0",
33
33
  "lucide-static": "^1.47.0",
34
34
  "pdfjs-dist": "^6.3.289",
35
35
  "playwright-core": "^1.63.0",
@@ -65,7 +65,7 @@
65
65
  "jsqr": "^1.4.0",
66
66
  "leaflet": "1.9.4",
67
67
  "maplibre-gl": "6.13.0",
68
- "mermaid": "^11.17.2"
68
+ "mermaid": "^12.1.0"
69
69
  },
70
70
  "scripts": {
71
71
  "dev": "node bin/sagadeck.js studio",
package/src/ai/context.js CHANGED
@@ -23,7 +23,12 @@ export async function extractDocText(name, buf) {
23
23
  if (buf.length > UPLOAD_MAX_BYTES) throw new Error(`Arquivo grande demais (${(buf.length / 1048576).toFixed(1)} MB, limite 15 MB).`);
24
24
  const ext = (String(name).match(/\.([a-z0-9]+)$/i)?.[1] || "").toLowerCase();
25
25
  if(ext==='doc')return {...await extractDocText('converted.docx',await convertLegacyWord(buf)),detail:'doc (convertido para docx)'};
26
- if (["txt", "md", "markdown", "csv", "json", "yaml", "yml"].includes(ext)) {
26
+ // Código é material da pessoa: espaços e linhas podem fazer parte de strings ou da sintaxe.
27
+ if (["js", "mjs", "cjs", "ts", "tsx", "jsx", "py", "sh", "bash", "ps1", "http", "sql", "go", "rs", "java", "c", "cpp", "h", "cs", "rb", "php", "html", "css"].includes(ext)) {
28
+ return { text: buf.toString("utf8"), detail: `código (.${ext})` };
29
+ }
30
+ if (["json", "jsonc", "yaml", "yml"].includes(ext)) return { text: buf.toString("utf8"), detail: "texto" };
31
+ if (["txt", "md", "markdown", "csv"].includes(ext)) {
27
32
  return { text: clean(buf.toString("utf8")), detail: "texto" };
28
33
  }
29
34
  if (ext === "docx") {
@@ -74,7 +79,7 @@ export async function extractDocText(name, buf) {
74
79
  return { text: clean(parts.join("\n\n")), detail: `xlsx (${sheets.length} planilha(s))` };
75
80
  }
76
81
  if (ext === "pdf") return pdfText(buf);
77
- throw new Error(`Tipo não suportado${ext ? ` (.${ext})` : ""}: vale txt, md, csv, docx, xlsx, pptx e pdf.`);
82
+ throw new Error(`Tipo não suportado${ext ? ` (.${ext})` : ""}: anexe texto, código (js, ts, py, sh, http, sql e outros), docx, xlsx, pptx ou pdf.`);
78
83
  }
79
84
 
80
85
  async function pdfText(buf) {