sagadeck 1.4.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -67
- package/SKILL.md +18 -11
- package/bin/sagadeck.js +12 -11
- package/docs/ANDAMENTO.md +355 -0
- package/docs/REFERENCIA.md +4 -4
- package/package.json +2 -3
- package/src/ai/bench.js +132 -0
- package/src/ai/context.js +4 -2
- package/src/ai/critique.js +114 -0
- package/src/ai/deck-ai.js +142 -32
- package/src/ai/document-visuals.js +7 -3
- package/src/ai/ia-config.js +101 -0
- package/src/ai/llm.js +62 -26
- package/src/ai/progress.js +23 -0
- package/src/ai/quality.js +30 -2
- package/src/api-client.js +2 -1
- package/src/build.js +3 -0
- package/src/decision-lab.js +2 -1
- package/src/deck-file.js +2 -1
- package/src/elements.js +10 -3
- package/src/figures/charts.js +7 -4
- package/src/figures/diagrams.js +15 -1
- package/src/figures/ufmap.js +2 -1
- package/src/fs-retry.js +19 -0
- package/src/layouts.js +1 -1
- package/src/library.js +75 -19
- package/src/locale.js +18 -0
- package/src/mcp/server.js +2 -2
- package/src/motion.js +5 -3
- package/src/preferences.js +5 -1
- package/src/research/research.js +6 -5
- package/src/runtime/calc.js +3 -3
- package/src/runtime/decision-lab.js +1 -1
- package/src/runtime/motion.js +5 -1
- package/src/runtime/runtime.js +2 -1
- package/src/studio/ai-chat-route.js +100 -4
- package/src/studio/banner.js +18 -0
- package/src/studio/code-version.js +35 -0
- package/src/studio/generate.js +53 -0
- package/src/studio/ia-routes.js +53 -0
- package/src/studio/project.js +8 -7
- package/src/studio/public/ai-settings.js +76 -0
- package/src/studio/public/app.js +11 -239
- package/src/studio/public/chat.js +71 -1
- package/src/studio/public/header-footer.js +140 -0
- package/src/studio/public/index.html +6 -0
- package/src/studio/public/library.html +3 -1
- package/src/studio/public/library.js +7 -5
- package/src/studio/public/preferences-ui.js +86 -0
- package/src/studio/public/provenance.js +13 -0
- package/src/studio/public/style.css +17 -0
- package/src/studio/public/ui-icons.js +1 -1
- package/src/studio/public/update-notice.js +25 -0
- package/src/studio/public-files.js +11 -1
- package/src/studio/server.js +26 -47
- package/src/studio/share-routes.js +2 -1
- package/src/studio/slide-copy.js +3 -1
- package/src/ai/relay.js +0 -45
package/README.md
CHANGED
|
@@ -14,19 +14,26 @@ Ele vem com 11 temas (incluindo estilo Keynote Apple em prata clean e respiráve
|
|
|
14
14
|
## Instalação
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
|
|
17
|
+
npm install -g sagadeck
|
|
18
18
|
```
|
|
19
|
-
Requer **Node.js 18+** e **Chrome ou Edge** instalados (o
|
|
19
|
+
Requer **Node.js 18+** e **Chrome ou Edge** instalados (o PDF, o PNG e as conferências visuais usam o navegador).
|
|
20
|
+
É tudo Node: não precisa de Python. (O pacote do PyPI parou na 1.5.0.)
|
|
21
|
+
|
|
22
|
+
## Comece aqui
|
|
20
23
|
|
|
21
|
-
Quem já vive no Node pode instalar direto, sem Python e sem bundle (vai a fonte + dependências):
|
|
22
24
|
```bash
|
|
23
|
-
|
|
25
|
+
sagadeck studio
|
|
24
26
|
```
|
|
25
|
-
|
|
27
|
+
e abra **http://127.0.0.1:3517** no navegador. **Essa é a página do sagadeck**: a biblioteca das suas
|
|
28
|
+
apresentações, o editor (estilo PowerPoint) e o chat com a IA. Não há outra interface para abrir nem para criar.
|
|
29
|
+
|
|
30
|
+
Para usar a IA (gerar apresentações, conversar com o chat), clique em **Configurar IA** no alto da biblioteca (ou
|
|
31
|
+
em **IA desligada**, no editor), escolha o provedor, cole a chave, clique em **Testar** e **Salvar**. Detalhes em
|
|
32
|
+
[IA de verdade](#ia-de-verdade-llm).
|
|
26
33
|
|
|
27
34
|
## Como usar
|
|
28
35
|
|
|
29
|
-
Toda apresentação mora na **biblioteca**: `SAGADECK_HOME`,
|
|
36
|
+
Toda apresentação mora na **biblioteca**: `SAGADECK_HOME`, senão a pasta `sagadeck` dentro de **Documentos** no Windows (a pasta Documentos que o Explorer mostra, mesmo redirecionada para o OneDrive ou outro disco) e `~/sagadeck` no Mac e no Linux. Quem usava a biblioteca antiga em `C:\Users\<você>\sagadeck` tem ela movida para Documentos na primeira execução; o caminho antigo continua levando até lá. Uma pasta por tópico, uma por apresentação.
|
|
30
37
|
|
|
31
38
|
```bash
|
|
32
39
|
sagadeck new "Minha palestra" --topic=Palestras --theme=editorial
|
|
@@ -69,64 +76,52 @@ O sagadeck foi projetado para ser usado por humanos e por agentes de IA:
|
|
|
69
76
|
2. **Pelo Estúdio Visual**: Execute `sagadeck studio palestra.yaml` para abrir a interface web estilo PowerPoint, onde você pode editar visualmente no canvas 16:9 e conversar com a IA no chat lateral. A IA se auto-corrige e nunca deixa elementos sobrepostos ou fora das margens.
|
|
70
77
|
3. **Pelo Protocolo MCP**: Execute `sagadeck mcp` para que IDEs agênticos (Cursor, Windsurf, Cline, Roo Code) descubram e invoquem diretamente as ferramentas de criação, leitura, fiscalização e auto-cura de apresentações.
|
|
71
78
|
|
|
72
|
-
Se o código de uma ferramenta em Python quiser chamar o sagadeck diretamente (sem montar comandos de terminal), há uma API mínima:
|
|
73
|
-
|
|
74
|
-
```python
|
|
75
|
-
import sagadeck
|
|
76
|
-
sagadeck.autofix("palestra.yaml") # corrige sobreposições e margens automaticamente
|
|
77
|
-
sagadeck.studio() # abre a biblioteca (~/sagadeck)
|
|
78
|
-
sagadeck.studio("palestra.yaml", port=3517) # abre direto o editor de um deck
|
|
79
|
-
sagadeck.export("palestra.yaml", out="saida") # {'html': …, 'pptx': …, 'pdf': …, 'roteiro': …}
|
|
80
|
-
print(sagadeck.check("palestra.yaml")) # relatório do fiscal em texto
|
|
81
|
-
contexto = sagadeck.reference() # referência do YAML para colocar no prompt
|
|
82
|
-
```
|
|
83
|
-
|
|
84
79
|
## IA de verdade (LLM)
|
|
85
80
|
|
|
86
|
-
O chat lateral do Studio, o Napkin (texto → slide), o **"
|
|
87
|
-
|
|
88
|
-
O sagadeck fala com qualquer endpoint compatível com OpenAI (`/v1/chat/completions`). O caminho recomendado é o [modelrelay](https://github.com/naruminho/modelrelay), que decide pela configuração dele para onde as chamadas vão (OpenRouter, OpenAI, gateway corporativo), sem nada disso no sagadeck:
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
pip install "sagadeck[ia]" # o sagadeck com o modelrelay na versão que ele exige
|
|
92
|
-
# ou só o modelrelay: pip install -U modelrelay
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
Com um modelrelay mais velho do que o exigido, o sagadeck avisa ao abrir e mostra o comando para atualizar.
|
|
96
|
-
Quem desenvolve o modelrelay e o instalou direto do clone (`pip install -e .` na pasta dele, a "instalação
|
|
97
|
-
editável": o Python lê o código da pasta, sem cópia) atualiza só com `git pull` ali, e o aviso diz isso, com a
|
|
98
|
-
pasta. `pip install -e .` de novo só quando o modelrelay ganhar uma dependência nova.
|
|
81
|
+
O chat lateral do Studio, o Napkin (texto → slide), o **"Deck com IA"** e a geração de imagens usam um LLM quando há um configurado; sem ele, o chat e o Napkin continuam funcionando com as regras locais.
|
|
99
82
|
|
|
100
|
-
O
|
|
101
|
-
|
|
102
|
-
(OpenRouter, OpenAI, Google, DeepSeek, o gateway da empresa…), cola a chave, testa e diz qual modelo faz
|
|
103
|
-
**texto** e qual faz **imagem**. A tela grava o `~/.modelrelay/config.toml`, que também dá para editar à mão
|
|
104
|
-
(`modelrelay init` cria um modelo comentado). O botão só aparece quando o modelrelay roda nesta máquina; no
|
|
105
|
-
modo multiusuário, quem configura é o admin.
|
|
83
|
+
O sagadeck fala direto com qualquer provedor compatível com a API da OpenAI (`/v1/chat/completions`): OpenRouter,
|
|
84
|
+
OpenAI, o proxy de IA da empresa. Não há serviço à parte para instalar nem para manter rodando.
|
|
106
85
|
|
|
107
|
-
|
|
86
|
+
**Pela tela** (o jeito mais fácil): **Configurar IA**, no alto da biblioteca, ou **IA desligada / IA ligada**, no
|
|
87
|
+
editor. Escolha o provedor (OpenRouter, OpenAI ou "outro compatível", com o endereço), cole a chave e diga o modelo
|
|
88
|
+
de cada papel:
|
|
108
89
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
90
|
+
| papel | para quê | |
|
|
91
|
+
|---|---|---|
|
|
92
|
+
| texto | chat, Napkin, geração e revisão de decks | obrigatório |
|
|
93
|
+
| visão | ver o slide renderizado e as imagens coladas | opcional; vazio = o de texto |
|
|
94
|
+
| imagem | ilustrações (`image_prompt`) | opcional |
|
|
95
|
+
| busca | pesquisa na web da geração (no OpenRouter, um modelo `:online`) | opcional; sem ele, buscadores diretos |
|
|
96
|
+
|
|
97
|
+
**Testar** faz uma pergunta curta com o que está na tela antes de salvar. A configuração fica só nesta máquina, em
|
|
98
|
+
`~/.sagadeck/ia.json` (fora do código e fora da biblioteca, que pode sincronizar com a nuvem); a chave nunca volta
|
|
99
|
+
inteira para a página. No modo multiusuário, quem configura é quem administra o servidor.
|
|
100
|
+
|
|
101
|
+
**À mão**, o mesmo arquivo:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"provider": "openrouter",
|
|
106
|
+
"url": "https://openrouter.ai/api/v1",
|
|
107
|
+
"keyEnv": "OPENROUTER_API_KEY",
|
|
108
|
+
"models": { "text": "deepseek/deepseek-v4.1-flash", "image": "google/gemini-3.1-flash-image" }
|
|
109
|
+
}
|
|
113
110
|
```
|
|
111
|
+
A chave vai em `key` ou numa variável de ambiente indicada em `keyEnv`. `headers` acrescenta cabeçalhos fixos.
|
|
114
112
|
|
|
115
|
-
|
|
116
|
-
|
|
113
|
+
**Provedor que não segue a API da OpenAI** (outro jeito de autenticar, outro endereço): em vez de mexer no sagadeck,
|
|
114
|
+
aponte `"adaptador"` para um arquivo `.mjs` seu cujo `export default` recebe `(url, init)` e devolve a resposta (como
|
|
115
|
+
o `fetch`). O resto do pedido segue no formato da OpenAI.
|
|
117
116
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
"text" = "deepseek/deepseek-v4-flash"
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
Confira com `modelrelay show --app sagadeck`. Detalhes na seção *Per-app models* do README do modelrelay.
|
|
117
|
+
**Quem usava o modelrelay**: na primeira vez, o sagadeck traz a configuração dele (`~/.modelrelay/config.toml`:
|
|
118
|
+
provedor, chave e os modelos do sagadeck) para o `~/.sagadeck/ia.json`. Depois disso o modelrelay não é mais usado.
|
|
124
119
|
|
|
125
120
|
**Modelo sem visão** (ex.: DeepSeek V4 Flash): o assistente manda uma foto do slide e as imagens que você cola.
|
|
126
121
|
Se o modelo recusar imagem, o sagadeck refaz o pedido sem as imagens, avisa na resposta ("não enxerga imagens")
|
|
127
122
|
e não insiste nesse modelo até reiniciar. Tudo funciona, só que a IA não vê o slide renderizado.
|
|
128
123
|
|
|
129
|
-
|
|
124
|
+
Na linha de comando, `new`, `napkin` e `imagens` usam a mesma configuração:
|
|
130
125
|
|
|
131
126
|
```bash
|
|
132
127
|
sagadeck new palestra --prompt "Palestra de 15 min para gerentes sobre IA com segurança. Ilustre onde fizer sentido." --slides=10
|
|
@@ -134,14 +129,15 @@ sagadeck napkin "1) cliente abre chamado 2) triagem por IA 3) analista revisa"
|
|
|
134
129
|
sagadeck imagens palestra.yaml # gera as imagens pedidas com image_prompt: no YAML
|
|
135
130
|
```
|
|
136
131
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
|
140
|
-
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
143
|
-
| `
|
|
144
|
-
| `
|
|
132
|
+
As variáveis abaixo valem por cima da configuração (útil em servidor e em testes):
|
|
133
|
+
|
|
134
|
+
| variável | |
|
|
135
|
+
|---|---|
|
|
136
|
+
| `SAGADECK_LLM_URL` | qualquer API compatível com OpenAI (ex.: `https://openrouter.ai/api/v1`) |
|
|
137
|
+
| `SAGADECK_LLM_KEY` | a chave (bearer token) |
|
|
138
|
+
| `SAGADECK_TEXT_MODEL` / `SAGADECK_VISION_MODEL` / `SAGADECK_IMAGE_MODEL` / `SAGADECK_SEARCH_MODEL` | os modelos de cada papel |
|
|
139
|
+
| `SAGADECK_LLM_TIMEOUT` | segundos por chamada (padrão `180`) |
|
|
140
|
+
| `SAGADECK_IA` | outro arquivo de configuração (padrão `~/.sagadeck/ia.json`) |
|
|
145
141
|
|
|
146
142
|
**Imagens geradas: você pede no texto**, no chat, no briefing do "Deck com IA" ou no `--prompt`; não há caixa para marcar.
|
|
147
143
|
"Com fotos em todos os slides" ilustra todos; "você decide onde ilustrar" deixa a IA escolher só os slides em que uma imagem
|
|
@@ -156,15 +152,13 @@ Todo YAML vindo do LLM é validado (renderiza cada slide); se falhar, o erro vol
|
|
|
156
152
|
```bash
|
|
157
153
|
npm install
|
|
158
154
|
node bin/sagadeck.js build templates/exemplo.yaml
|
|
159
|
-
npm run bundle # empacota o motor em python/sagadeck/engine
|
|
160
|
-
npm run build:py # gera dist/*.whl e dist/*.tar.gz
|
|
161
155
|
npm test # suíte inteira: motor + runtime + Studio (clicando num Chrome headless)
|
|
162
156
|
npm run test:unit # só o motor (rápido, sem navegador)
|
|
163
|
-
SAGADECK_LIVE=1 npm test # inclui os testes que chamam o LLM de verdade (
|
|
157
|
+
SAGADECK_LIVE=1 npm test # inclui os testes que chamam o LLM de verdade (o configurado em Configurar IA)
|
|
164
158
|
```
|
|
165
159
|
**Toda funcionalidade nova entra com teste** em `test/` — é o que garante que um refactor não apague o que já funciona. Veja [CLAUDE.md](CLAUDE.md).
|
|
166
160
|
|
|
167
|
-
Publicação: crie uma release `vX.Y.Z` no GitHub
|
|
161
|
+
Publicação: com a CI verde, crie uma release `vX.Y.Z` no GitHub; o workflow `.github/workflows/publish.yml` publica no npm (*trusted publishing*). A versão fica em `package.json`.
|
|
168
162
|
|
|
169
163
|
## Arquivo `.sagadeck` (a apresentação inteira)
|
|
170
164
|
|
|
@@ -193,7 +187,7 @@ formato avisa para atualizar o sagadeck. Se um filtro de e-mail barrar a extens
|
|
|
193
187
|
## Biblioteca
|
|
194
188
|
|
|
195
189
|
`sagadeck studio` sem arquivo abre a biblioteca: suas apresentações organizadas em tópicos, com capa, busca,
|
|
196
|
-
lixeira (30 dias) e o menu **⋯** de cada cartão (apresentar, renomear, duplicar, mover, baixar tudo/.sagadeck/PPTX/PDF).
|
|
190
|
+
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).
|
|
197
191
|
|
|
198
192
|
**Nova apresentação** tem três caminhos: *Descrever com IA* (o assunto, quanto tempo você tem, que vira o número de
|
|
199
193
|
slides, o estilo e, se quiser, material de apoio: PDF, Word, PowerPoint, Excel ou um link), *A partir de um arquivo
|
|
@@ -205,7 +199,7 @@ Arraste um cartão para um tópico para movê-lo. O ícone da biblioteca, no can
|
|
|
205
199
|
Não tem banco de dados: a biblioteca é uma pasta comum, que dá para abrir no Explorer e fazer backup.
|
|
206
200
|
|
|
207
201
|
```text
|
|
208
|
-
~/sagadeck/
|
|
202
|
+
Documentos/sagadeck/ (Windows; ~/sagadeck no Mac/Linux; ou SAGADECK_HOME, ou --library=PASTA)
|
|
209
203
|
Palestras/ tópico = pasta (a cor fica em .topico.json)
|
|
210
204
|
Minha palestra/ apresentação = pasta com o YAML e os arquivos dela
|
|
211
205
|
Minha palestra.yaml
|
|
@@ -301,8 +295,6 @@ src/export/ PowerPoint, PDF, imagens, roteiro e o fiscal
|
|
|
301
295
|
templates/exemplo.yaml deck de exemplo com todos os layouts
|
|
302
296
|
docs/REFERENCIA.md referência completa do YAML
|
|
303
297
|
SKILL.md instruções para IAs gerarem decks com o sagadeck
|
|
304
|
-
python/sagadeck/ pacote Python (CLI + API) que carrega o motor empacotado
|
|
305
|
-
scripts/bundle.mjs empacota o motor para o pip
|
|
306
298
|
tools/ppt-render.ps1 renderiza um .pptx pelo PowerPoint (para conferir fidelidade)
|
|
307
299
|
tools/test-live.mjs teste automático do modo apresentação e dos widgets
|
|
308
300
|
```
|
package/SKILL.md
CHANGED
|
@@ -7,15 +7,30 @@ description: Gera apresentações bonitas (HTML animado + PowerPoint editável +
|
|
|
7
7
|
|
|
8
8
|
O sagadeck gera apresentações profissionais a partir de um arquivo YAML, oferecendo tanto linha de comando (CLI), estúdio web visual no estilo PowerPoint, quanto protocolo MCP para integração com IDEs agênticos (Claude Code, Cursor, Windsurf, Cline, Roo Code).
|
|
9
9
|
|
|
10
|
+
## Para agentes: "deixar pronto para usar"
|
|
11
|
+
|
|
12
|
+
Quando a pessoa pede para instalar o sagadeck e deixar pronto:
|
|
13
|
+
|
|
14
|
+
1. `npm install -g sagadeck` (Node 18+; não precisa de Python).
|
|
15
|
+
2. `sagadeck studio` e diga para ela abrir **http://127.0.0.1:3517** (a primeira linha que o comando escreve é
|
|
16
|
+
esse endereço). **O Studio é a interface do sagadeck**: biblioteca, editor e chat com IA.
|
|
17
|
+
3. **Nunca crie uma página, um servidor ou uma interface própria** para o sagadeck, nem "suba as APIs" à mão: tudo
|
|
18
|
+
que a pessoa precisa está no Studio.
|
|
19
|
+
4. Para a IA, mostre onde configurar: **Configurar IA** no alto da biblioteca (ou **IA desligada** no editor):
|
|
20
|
+
provedor, chave, Testar e Salvar. A configuração fica em `~/.sagadeck/ia.json`; nunca grave a chave no código nem
|
|
21
|
+
na pasta das apresentações.
|
|
22
|
+
5. As apresentações moram na biblioteca (`SAGADECK_HOME`, senão Documentos\sagadeck no Windows e `~/sagadeck` fora
|
|
23
|
+
dele). Não crie decks em outra pasta.
|
|
24
|
+
|
|
10
25
|
## Comandos Disponíveis
|
|
11
26
|
|
|
12
27
|
| comando | o que faz |
|
|
13
28
|
|---|---|
|
|
14
|
-
| `sagadeck studio [deck.yaml] [--port=
|
|
29
|
+
| `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**. |
|
|
15
30
|
| `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. |
|
|
16
31
|
| `sagadeck search "<termo>"` | **Pesquisa web sem bloqueio (DuckDuckGo)**: busca dados reais, números e referências confiáveis para enriquecer os slides. |
|
|
17
32
|
| `sagadeck mcp` | **Servidor MCP**: expõe ferramentas padronizadas (JSON-RPC) para IDEs agênticos criarem, lerem, pesquisarem, fiscalizarem e editarem decks. |
|
|
18
|
-
| `sagadeck new
|
|
33
|
+
| `sagadeck new "<nome>" [--topic=T] [--theme=prata]` | cria um deck de exemplo na biblioteca |
|
|
19
34
|
| `sagadeck build deck.yaml` | compila `deck.html` standalone (abre no navegador; tecla P = modo apresentador) |
|
|
20
35
|
| `sagadeck check deck.yaml` | fiscal: texto estourado, sobreposição, contraste, fonte pequena, excesso de texto |
|
|
21
36
|
| `sagadeck pptx deck.yaml` | gera `deck.pptx` **totalmente editável** no PowerPoint com formas e caixas nativas |
|
|
@@ -99,14 +114,6 @@ O agente no terminal deve seguir o fluxo:
|
|
|
99
114
|
3. Rodar `sagadeck check deck.yaml` para confirmar ausência de avisos.
|
|
100
115
|
4. Rodar `sagadeck all deck.yaml` para gerar todas as entregas.
|
|
101
116
|
|
|
102
|
-
### 3. Via API Python
|
|
103
|
-
```python
|
|
104
|
-
import sagadeck
|
|
105
|
-
sagadeck.autofix("palestra.yaml")
|
|
106
|
-
sagadeck.build("palestra.yaml")
|
|
107
|
-
sagadeck.studio("palestra.yaml", port=3000)
|
|
108
|
-
```
|
|
109
|
-
|
|
110
117
|
---
|
|
111
118
|
|
|
112
119
|
## Decisão de Arquitetura: Mesmo Repositório vs. Repositório Separado
|
|
@@ -114,7 +121,7 @@ sagadeck.studio("palestra.yaml", port=3000)
|
|
|
114
121
|
### Por que o Estúdio deve ficar no **mesmo repositório** (`sagadeck`):
|
|
115
122
|
1. **Fonte Única da Verdade**: Os layouts (incluindo `stats` para KPIs e `steps` para processos), os 11 temas visuais (incluindo `prata` estilo Keynote Apple, `rabisco` artesanal pintado à mão, `oceano` azul elétrico vivo, `pop` alegre/chiclete e `aurora` neon), as regras de tipografia e as rotinas de verificação geométrica residem no mesmo código (`src/layouts.js`, `src/themes.js`, `src/fiscal/autofix.js`). Qualquer alteração ou novo layout adicionado ao compilador fica disponível **instantaneamente** no estúdio visual.
|
|
116
123
|
2. **Zero Descompasso de Versões**: Em repositórios separados, quando o formato YAML ou os temas do SagaDeck evoluem, a interface visual quebra ou fica desatualizada até que alguém publique e atualize dependências externas.
|
|
117
|
-
3. **Experiência de Uso (DX) Imediata**: O desenvolvedor ou agente clona o repositório ou roda `
|
|
124
|
+
3. **Experiência de Uso (DX) Imediata**: O desenvolvedor ou agente clona o repositório ou roda `npm install -g sagadeck` e tem **tudo num só lugar**: linha de comando (`sagadeck build`), estúdio visual (`sagadeck studio`), servidor de agentes (`sagadeck mcp`) e fiscal (`sagadeck check`).
|
|
118
125
|
4. **Leve e Modular**: A interface web foi construída com tecnologias nativas leves (Vanilla JS, CSS moderno e servidor HTTP embutido do Node.js sem frameworks pesados). Isso mantém o pacote pequeno (~1.1 MB empacotado) sem impactar o desempenho do compilador.
|
|
119
126
|
|
|
120
127
|
---
|
package/bin/sagadeck.js
CHANGED
|
@@ -57,7 +57,7 @@ const HELP = `sagadeck — YAML -> apresentação (HTML animado + PowerPoint edi
|
|
|
57
57
|
sagadeck estudo <deck.yaml> [--html] gera <deck> - material de estudo.pdf (cada slide + texto de consulta)
|
|
58
58
|
sagadeck all <deck.yaml> build + check + pptx + pdf + roteiro
|
|
59
59
|
sagadeck studio [deck.yaml|x.sagadeck] [--port=3517] [--library=PASTA] sem arquivo: abre a biblioteca; já aberto: usa o aberto
|
|
60
|
-
(PASTA padrão: SAGADECK_HOME
|
|
60
|
+
(PASTA padrão: SAGADECK_HOME, senão Documentossagadeck no Windows, ~/sagadeck fora dele); com arquivo: abre o editor dele
|
|
61
61
|
--host=0.0.0.0 abre para a rede (padrão: só esta máquina)
|
|
62
62
|
--multiuser: uma biblioteca por usuário, atrás de um proxy que envia X-Sagadeck-User
|
|
63
63
|
--agentes=naru,ana: no multiusuário, quem pode deixar a IA rodar comandos (padrão: ninguém)
|
|
@@ -124,6 +124,14 @@ async function doShots(p, dir = p.shots) {
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
async function main() {
|
|
127
|
+
// biblioteca antiga (~/sagadeck) vai para Documentos\sagadeck no Windows, uma vez (src/library.js)
|
|
128
|
+
if (!flags.library) {
|
|
129
|
+
const { migrateLegacyLibrary } = await import("../src/library.js");
|
|
130
|
+
const m = migrateLegacyLibrary();
|
|
131
|
+
if (m.moved) console.log(`✓ biblioteca movida para ${m.target} (o caminho antigo ${m.legacy} continua levando até ela)`);
|
|
132
|
+
else if (m.error) console.log(`! não deu para mover a biblioteca para ${m.target} (${m.error}); sigo usando ${m.legacy}`);
|
|
133
|
+
else if (m.skipped === "as duas têm conteúdo") console.log(`! há apresentações em ${m.legacy} e em ${m.target}; uso ${m.target}. Junte as duas pelo Explorer se quiser.`);
|
|
134
|
+
}
|
|
127
135
|
switch (cmd) {
|
|
128
136
|
case "napkin":
|
|
129
137
|
case "visual": {
|
|
@@ -386,22 +394,15 @@ async function main() {
|
|
|
386
394
|
process.exit(1);
|
|
387
395
|
}
|
|
388
396
|
const agentUsers = typeof flags.agentes === "string" ? flags.agentes.split(",").map((x) => x.trim()).filter(Boolean) : undefined;
|
|
389
|
-
// IA: sobe o `modelrelay serve` junto, se ele estiver instalado e ninguém escutar na porta dele (como o sagadeck do pip)
|
|
390
|
-
const { startRelay } = await import("../src/ai/relay.js");
|
|
391
|
-
const relay = multiuser ? null : await startRelay();
|
|
392
|
-
if (relay) {
|
|
393
|
-
console.log(`✓ IA: modelrelay em ${relay.url} (configuração: http://127.0.0.1:8765/)`);
|
|
394
|
-
for (const sig of ["exit", "SIGINT", "SIGTERM"]) process.on(sig, () => { relay.stop(); if (sig !== "exit") process.exit(0); });
|
|
395
|
-
}
|
|
396
397
|
const server = createStudioServer(deckFile, { port, host, library, multiuser, userHeader: flags["user-header"], agentUsers });
|
|
397
398
|
server.on("error", (e) => {
|
|
398
399
|
if (e.code !== "EADDRINUSE") throw e;
|
|
399
400
|
console.error(`A porta ${port} está ocupada por outro programa. Use --port=OUTRA.`);
|
|
400
401
|
process.exit(1);
|
|
401
402
|
});
|
|
402
|
-
server.listen(port, host, () => {
|
|
403
|
-
|
|
404
|
-
|
|
403
|
+
server.listen(port, host, async () => {
|
|
404
|
+
const { studioBanner } = await import("../src/studio/banner.js");
|
|
405
|
+
for (const line of studioBanner({ version: VERSION, url: `http://${shownHost}:${port}/`, library, ai: (await import("../src/ai/llm.js")).llmConfig(), multiuser, usersDir: path.join(library, "usuarios"), isLibrary: !deckFile })) console.log(line);
|
|
405
406
|
});
|
|
406
407
|
break;
|
|
407
408
|
}
|