primocode 11.0.0 → 11.1.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 +4 -4
- package/agentes/algoritmos.md +10 -0
- package/agentes/angular.md +10 -0
- package/agentes/animacao-web.md +10 -0
- package/agentes/anuncios.md +10 -0
- package/agentes/apresentacao.md +10 -0
- package/agentes/arquitetura.md +10 -0
- package/agentes/audio.md +10 -0
- package/agentes/auth.md +10 -0
- package/agentes/automacao.md +10 -0
- package/agentes/bash.md +10 -0
- package/agentes/blockchain.md +10 -0
- package/agentes/brand.md +10 -0
- package/agentes/canvas.md +10 -0
- package/agentes/ci-cd.md +10 -0
- package/agentes/cloud.md +10 -0
- package/agentes/cores.md +10 -0
- package/agentes/cpp.md +10 -0
- package/agentes/csharp.md +10 -0
- package/agentes/css-layout.md +1 -1
- package/agentes/dados-sql-analise.md +10 -0
- package/agentes/depuracao.md +1 -1
- package/agentes/design-system.md +10 -0
- package/agentes/docker.md +10 -0
- package/agentes/electron.md +10 -0
- package/agentes/email-mkt.md +10 -0
- package/agentes/extensao-chrome.md +10 -0
- package/agentes/filas.md +10 -0
- package/agentes/firebase.md +10 -0
- package/agentes/flutter.md +10 -0
- package/agentes/games.md +10 -0
- package/agentes/geral/capacidades/backend.json +246 -0
- package/agentes/geral/capacidades/banco.json +186 -0
- package/agentes/geral/capacidades/codigo.json +576 -0
- package/agentes/geral/capacidades/depuracao.json +570 -0
- package/agentes/geral/capacidades/design.json +246 -0
- package/agentes/geral/capacidades/devops.json +240 -0
- package/agentes/geral/capacidades/frontend.json +252 -0
- package/agentes/geral/capacidades/git.json +558 -0
- package/agentes/geral/capacidades/ia-llm.json +246 -0
- package/agentes/geral/capacidades/marketing.json +252 -0
- package/agentes/geral/capacidades/mobile.json +192 -0
- package/agentes/geral/capacidades/produto-negocio.json +186 -0
- package/agentes/geral/capacidades/shell.json +522 -0
- package/agentes/geral/capacidades/testes.json +186 -0
- package/agentes/geral/capacidades/video-motion.json +246 -0
- package/agentes/geral/capacidades/windows-linux.json +216 -0
- package/agentes/go.md +10 -0
- package/agentes/graphql.md +10 -0
- package/agentes/growth.md +10 -0
- package/agentes/ia-evals.md +10 -0
- package/agentes/ilustracao.md +10 -0
- package/agentes/indice.md +1 -86
- package/agentes/iot.md +10 -0
- package/agentes/java.md +10 -0
- package/agentes/javascript.md +10 -0
- package/agentes/juridico-basico.md +10 -0
- package/agentes/kotlin.md +10 -0
- package/agentes/kubernetes.md +10 -0
- package/agentes/landing.md +10 -0
- package/agentes/legado.md +10 -0
- package/agentes/linux.md +10 -0
- package/agentes/llm-prompts.md +10 -0
- package/agentes/mcp.md +10 -0
- package/agentes/ml.md +10 -0
- package/agentes/mongodb.md +10 -0
- package/agentes/motion.md +10 -0
- package/agentes/negocio.md +10 -0
- package/agentes/observabilidade.md +10 -0
- package/agentes/orm.md +10 -0
- package/agentes/pagamentos.md +10 -0
- package/agentes/pentest.md +10 -0
- package/agentes/performance.md +1 -1
- package/agentes/pesquisa-usuario.md +10 -0
- package/agentes/php.md +10 -0
- package/agentes/planilhas.md +10 -0
- package/agentes/privacidade.md +10 -0
- package/agentes/produto.md +10 -0
- package/agentes/pwa.md +10 -0
- package/agentes/qa-manual.md +10 -0
- package/agentes/raspagem.md +10 -0
- package/agentes/react-native.md +10 -0
- package/agentes/rede.md +10 -0
- package/agentes/redis.md +10 -0
- package/agentes/regex.md +10 -0
- package/agentes/revisao-texto.md +10 -0
- package/agentes/ruby.md +10 -0
- package/agentes/rust.md +10 -0
- package/agentes/seo.md +10 -0
- package/agentes/social.md +10 -0
- package/agentes/svelte.md +10 -0
- package/agentes/swift.md +10 -0
- package/agentes/tailwind.md +10 -0
- package/agentes/testes-carga.md +10 -0
- package/agentes/testes-e2e.md +10 -0
- package/agentes/testes-unit.md +10 -0
- package/agentes/thumbnails.md +10 -0
- package/agentes/tipografia.md +10 -0
- package/agentes/traducao.md +10 -0
- package/agentes/ui-mobile.md +10 -0
- package/agentes/video-edicao.md +10 -0
- package/agentes/video-roteiro.md +10 -0
- package/agentes/visualizacao.md +10 -0
- package/agentes/vue.md +10 -0
- package/agentes/web3d.md +10 -0
- package/agentes/websocket.md +10 -0
- package/bin/primocode.js +3 -4209
- package/editor/modelo-projeto/build.py +12 -4
- package/kits/KITS.md +4 -0
- package/lib/agentes/index.js +47 -4
- package/lib/agentes/nucleo.js +1 -1
- package/lib/agents-md.js +1 -1
- package/lib/app-chat.js +1 -1
- package/lib/backup-banco.js +1 -1
- package/lib/browser.js +7 -3
- package/lib/cli/boas-vindas.js +153 -0
- package/lib/cli/comando-api.js +85 -0
- package/lib/cli/comandos-extra.js +553 -0
- package/lib/cli/comandos.js +104 -0
- package/lib/cli/headless.js +102 -0
- package/lib/cli/sessao.js +4152 -0
- package/lib/cli/statusline.js +52 -0
- package/lib/cli/util.js +2 -2
- package/lib/conferir.js +4 -4
- package/lib/config/config.js +414 -0
- package/lib/config/limites.js +100 -0
- package/lib/cursor.js +3 -3
- package/lib/diff.js +1 -1
- package/lib/effort.js +1 -1
- package/lib/entrega.js +1 -1
- package/lib/escopo.js +1 -1
- package/lib/explicar.js +1 -1
- package/lib/fala.js +2 -2
- package/lib/guardar.js +2 -2
- package/lib/mcp/mcp.js +819 -0
- package/lib/memoria-usuario.js +1 -1
- package/lib/mudou.js +1 -1
- package/lib/nome-projeto.js +1 -1
- package/lib/nuvem.js +2 -2
- package/lib/permission/perigo.js +401 -0
- package/lib/permission/permissao.js +137 -0
- package/lib/permission/sandbox.js +252 -0
- package/lib/placar.js +1 -1
- package/lib/plano-previo.js +1 -1
- package/lib/plugin/auto-preview.js +71 -0
- package/lib/plugin/autoteste.js +1 -0
- package/lib/plugin/desktop.js +756 -0
- package/lib/plugin/editor-pro-maquina.js +355 -0
- package/lib/plugin/editor-pro.js +1022 -0
- package/lib/plugin/entregaveis/carrossel.js +93 -0
- package/lib/plugin/entregaveis/cartaz.js +112 -0
- package/lib/plugin/entregaveis/cli.js +36 -0
- package/lib/plugin/entregaveis/documento.js +169 -0
- package/lib/plugin/entregaveis/especialistas.js +72 -0
- package/lib/plugin/entregaveis/nucleo.js +243 -0
- package/lib/plugin/entregaveis/slides.js +232 -0
- package/lib/plugin/estudio/acervo.js +418 -0
- package/lib/plugin/estudio/assets.js +497 -0
- package/lib/plugin/estudio/assinatura.js +108 -0
- package/lib/plugin/estudio/conferencia-visual.js +76 -0
- package/lib/plugin/estudio/conferir-quadros.js +56 -0
- package/lib/plugin/estudio/cota.js +157 -0
- package/lib/plugin/estudio/diretor.js +392 -0
- package/lib/plugin/estudio/editor.js +290 -0
- package/lib/plugin/estudio/gosto-descrever.js +87 -0
- package/lib/plugin/estudio/gosto.js +608 -0
- package/lib/plugin/estudio/identidade.js +560 -0
- package/lib/plugin/estudio/index.js +2712 -0
- package/lib/plugin/estudio/kit.js +91 -0
- package/lib/plugin/estudio/kits-tela.js +199 -0
- package/lib/plugin/estudio/kokoro.js +127 -0
- package/lib/plugin/estudio/maquina-foto.js +177 -0
- package/lib/plugin/estudio/maquina-trilha.js +199 -0
- package/lib/plugin/estudio/maquina-voz.js +429 -0
- package/lib/plugin/estudio/marca.js +398 -0
- package/lib/plugin/estudio/materiais.js +218 -0
- package/lib/plugin/estudio/morfar.js +191 -0
- package/lib/plugin/estudio/print-site.js +341 -0
- package/lib/plugin/estudio/projeto.js +340 -0
- package/lib/plugin/estudio/projetos.js +72 -0
- package/lib/plugin/kits-parecidos.js +99 -0
- package/lib/plugin/kits.js +585 -0
- package/lib/plugin/marca-kit.js +312 -0
- package/lib/plugin/motioncraft.js +67 -0
- package/lib/plugin/pesquisar.js +7 -4
- package/lib/plugin/video/analise.js +89 -0
- package/lib/plugin/video/projeto.js +133 -0
- package/lib/plugin/video/rastrear.js +95 -0
- package/lib/plugin/video/render.js +274 -0
- package/lib/plugin/video/transcript.js +124 -0
- package/lib/plugin/voz-ponte.js +15 -0
- package/lib/plugin/voz.js +532 -0
- package/lib/porta.js +4 -4
- package/lib/pre-leitura.js +2 -2
- package/lib/preparar.js +11 -11
- package/lib/provider/api.js +310 -0
- package/lib/provider/claude-engine.js +673 -0
- package/lib/provider/codex-engine.js +225 -0
- package/lib/provider/local/motor-cli.js +93 -0
- package/lib/provider/local/motor.js +267 -0
- package/lib/provider/local/provedor.js +169 -0
- package/lib/publicar.js +2 -2
- package/lib/registro.js +2 -2
- package/lib/repeticao.js +2 -2
- package/lib/segredos.js +2 -2
- package/lib/session/checkpoint-git.js +221 -0
- package/lib/session/checkpoint.js +366 -0
- package/lib/session/compactacao.js +1 -1
- package/lib/session/exportar-conversa.js +49 -0
- package/lib/session/linha-do-tempo.js +130 -0
- package/lib/session/runner/act.js +2522 -0
- package/lib/skill/catalogo.js +367 -0
- package/lib/skill/marketplace.js +189 -0
- package/lib/skill/skills.js +468 -0
- package/lib/team.js +4 -4
- package/lib/tool/diagnostico.js +14 -3
- package/lib/tool/lsp.js +211 -0
- package/lib/tool/perguntar.js +55 -1
- package/lib/tool/tools.js +1095 -0
- package/lib/trava.js +1 -1
- package/lib/travado.js +1 -1
- package/lib/tui/entrada.js +1031 -0
- package/lib/tui/tela.js +245 -0
- package/lib/tui/ui.js +763 -0
- package/materiais/adesivos/base.ts +101 -0
- package/materiais/adesivos/camera/CameraDeriva.tsx +37 -0
- package/materiais/adesivos/cores/paleta.json +30 -0
- package/materiais/adesivos/cores/paleta.png +0 -0
- package/materiais/adesivos/formas/AdesivoForma.tsx +42 -0
- package/materiais/adesivos/formas/AdesivoFoto.tsx +36 -0
- package/materiais/adesivos/formas/SeloPreco.tsx +38 -0
- package/materiais/adesivos/pecas.json +496 -0
- package/materiais/adesivos/referencia/analise.md +85 -0
- package/materiais/adesivos/referencia/quadro-1.png +0 -0
- package/materiais/adesivos/referencia/quadro-2.png +0 -0
- package/materiais/adesivos/referencia/quadro-3.png +0 -0
- package/materiais/adesivos/referencia/quadro-4.png +0 -0
- package/materiais/adesivos/referencia/referencia.mp4 +0 -0
- package/materiais/adesivos/regras.md +138 -0
- package/materiais/adesivos/sons/Som.tsx +33 -0
- package/materiais/adesivos/texturas/ChuvaDeAdesivos.tsx +29 -0
- package/materiais/adesivos/texturas/Fundo.tsx +21 -0
- package/materiais/adesivos/texturas/Particulas.tsx +22 -0
- package/materiais/adesivos/tipografia/AdesivoTexto.tsx +35 -0
- package/materiais/adesivos/tipografia/AssinaturaMarca.tsx +36 -0
- package/materiais/adesivos/tipografia/TituloEtiquetas.tsx +33 -0
- package/materiais/adesivos/transicoes/Cena.tsx +48 -0
- package/materiais/adesivos/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/antes-depois/base.ts +82 -0
- package/materiais/antes-depois/camera/CameraDeriva.tsx +37 -0
- package/materiais/antes-depois/cores/paleta.json +28 -0
- package/materiais/antes-depois/cores/paleta.png +0 -0
- package/materiais/antes-depois/formas/BarraMedidor.tsx +43 -0
- package/materiais/antes-depois/formas/FaixaMarquee.tsx +35 -0
- package/materiais/antes-depois/formas/ListaMudancas.tsx +37 -0
- package/materiais/antes-depois/formas/RotuloAntesDepois.tsx +26 -0
- package/materiais/antes-depois/formas/TelaDividida.tsx +68 -0
- package/materiais/antes-depois/pecas.json +520 -0
- package/materiais/antes-depois/referencia/analise.md +85 -0
- package/materiais/antes-depois/referencia/quadro-1.png +0 -0
- package/materiais/antes-depois/referencia/quadro-2.png +0 -0
- package/materiais/antes-depois/referencia/quadro-3.png +0 -0
- package/materiais/antes-depois/referencia/quadro-4.png +0 -0
- package/materiais/antes-depois/referencia/referencia.mp4 +0 -0
- package/materiais/antes-depois/regras.md +141 -0
- package/materiais/antes-depois/sons/Som.tsx +40 -0
- package/materiais/antes-depois/texturas/Fundo.tsx +24 -0
- package/materiais/antes-depois/texturas/Particulas.tsx +22 -0
- package/materiais/antes-depois/tipografia/NumeroDelta.tsx +36 -0
- package/materiais/antes-depois/transicoes/Cena.tsx +41 -0
- package/materiais/antes-depois/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/apple-tipografico/base.ts +111 -0
- package/materiais/apple-tipografico/camera/Camera.tsx +23 -0
- package/materiais/apple-tipografico/camera/CameraDeriva.tsx +37 -0
- package/materiais/apple-tipografico/cores/paleta.json +21 -0
- package/materiais/apple-tipografico/cores/paleta.png +0 -0
- package/materiais/apple-tipografico/formas/CartaoRadial.tsx +41 -0
- package/materiais/apple-tipografico/formas/Produto3D.tsx +126 -0
- package/materiais/apple-tipografico/formas/ProdutoFoto.tsx +47 -0
- package/materiais/apple-tipografico/lib/produto3d-apoio.ts +22 -0
- package/materiais/apple-tipografico/pecas.json +491 -0
- package/materiais/apple-tipografico/referencia/analise.md +87 -0
- package/materiais/apple-tipografico/referencia/quadro-1.png +0 -0
- package/materiais/apple-tipografico/referencia/quadro-2.png +0 -0
- package/materiais/apple-tipografico/referencia/quadro-3.png +0 -0
- package/materiais/apple-tipografico/referencia/quadro-4.png +0 -0
- package/materiais/apple-tipografico/referencia/referencia.mp4 +0 -0
- package/materiais/apple-tipografico/regras.md +171 -0
- package/materiais/apple-tipografico/sons/Som.tsx +40 -0
- package/materiais/apple-tipografico/texturas/Fundo.tsx +21 -0
- package/materiais/apple-tipografico/texturas/Particulas.tsx +22 -0
- package/materiais/apple-tipografico/tipografia/AssinaturaPreta.tsx +33 -0
- package/materiais/apple-tipografico/tipografia/LegendaCurta.tsx +51 -0
- package/materiais/apple-tipografico/transicoes/Cena.tsx +55 -0
- package/materiais/apple-tipografico/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/aquarela/base.ts +97 -0
- package/materiais/aquarela/camera/CameraDeriva.tsx +37 -0
- package/materiais/aquarela/cores/paleta.json +30 -0
- package/materiais/aquarela/cores/paleta.png +0 -0
- package/materiais/aquarela/formas/AnotacaoManual.tsx +40 -0
- package/materiais/aquarela/formas/ManchaTinta.tsx +46 -0
- package/materiais/aquarela/formas/Pincelada.tsx +43 -0
- package/materiais/aquarela/formas/Pingos.tsx +31 -0
- package/materiais/aquarela/pecas.json +498 -0
- package/materiais/aquarela/referencia/analise.md +87 -0
- package/materiais/aquarela/referencia/quadro-1.png +0 -0
- package/materiais/aquarela/referencia/quadro-2.png +0 -0
- package/materiais/aquarela/referencia/quadro-3.png +0 -0
- package/materiais/aquarela/referencia/quadro-4.png +0 -0
- package/materiais/aquarela/referencia/referencia.mp4 +0 -0
- package/materiais/aquarela/regras.md +141 -0
- package/materiais/aquarela/sons/Som.tsx +33 -0
- package/materiais/aquarela/texturas/Fundo.tsx +24 -0
- package/materiais/aquarela/texturas/PapelRasgado.tsx +50 -0
- package/materiais/aquarela/texturas/Particulas.tsx +22 -0
- package/materiais/aquarela/tipografia/AssinaturaMarca.tsx +33 -0
- package/materiais/aquarela/tipografia/TituloPincel.tsx +51 -0
- package/materiais/aquarela/transicoes/Cena.tsx +48 -0
- package/materiais/aquarela/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/aurora/base.ts +93 -0
- package/materiais/aurora/camera/CameraDeriva.tsx +37 -0
- package/materiais/aurora/cores/paleta.json +30 -0
- package/materiais/aurora/cores/paleta.png +0 -0
- package/materiais/aurora/formas/CartaoVidro.tsx +29 -0
- package/materiais/aurora/formas/CeuEstrelado.tsx +22 -0
- package/materiais/aurora/formas/Montanhas.tsx +24 -0
- package/materiais/aurora/pecas.json +485 -0
- package/materiais/aurora/referencia/analise.md +84 -0
- package/materiais/aurora/referencia/quadro-1.png +0 -0
- package/materiais/aurora/referencia/quadro-2.png +0 -0
- package/materiais/aurora/referencia/quadro-3.png +0 -0
- package/materiais/aurora/referencia/quadro-4.png +0 -0
- package/materiais/aurora/referencia/referencia.mp4 +0 -0
- package/materiais/aurora/regras.md +140 -0
- package/materiais/aurora/sons/Som.tsx +33 -0
- package/materiais/aurora/texturas/Fundo.tsx +35 -0
- package/materiais/aurora/texturas/Particulas.tsx +22 -0
- package/materiais/aurora/tipografia/AssinaturaMarca.tsx +24 -0
- package/materiais/aurora/tipografia/Legenda.tsx +23 -0
- package/materiais/aurora/tipografia/TituloSerif.tsx +36 -0
- package/materiais/aurora/transicoes/Cena.tsx +48 -0
- package/materiais/aurora/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/aurora/transicoes/CortinaDeLuz.tsx +36 -0
- package/materiais/bauhaus/base.ts +74 -0
- package/materiais/bauhaus/camera/Camera.tsx +21 -0
- package/materiais/bauhaus/camera/CameraDeriva.tsx +37 -0
- package/materiais/bauhaus/cores/paleta.json +27 -0
- package/materiais/bauhaus/cores/paleta.png +0 -0
- package/materiais/bauhaus/formas/BarraDiagonal.tsx +20 -0
- package/materiais/bauhaus/formas/ComposicaoGeometrica.tsx +54 -0
- package/materiais/bauhaus/formas/ListaFaixas.tsx +27 -0
- package/materiais/bauhaus/formas/Overlay.tsx +18 -0
- package/materiais/bauhaus/pecas.json +520 -0
- package/materiais/bauhaus/referencia/analise.md +81 -0
- package/materiais/bauhaus/referencia/quadro-1.png +0 -0
- package/materiais/bauhaus/referencia/quadro-2.png +0 -0
- package/materiais/bauhaus/referencia/quadro-3.png +0 -0
- package/materiais/bauhaus/referencia/quadro-4.png +0 -0
- package/materiais/bauhaus/referencia/referencia.mp4 +0 -0
- package/materiais/bauhaus/regras.md +127 -0
- package/materiais/bauhaus/sons/Som.tsx +30 -0
- package/materiais/bauhaus/texturas/Fundo.tsx +13 -0
- package/materiais/bauhaus/texturas/Particulas.tsx +22 -0
- package/materiais/bauhaus/tipografia/AssinaturaMarca.tsx +26 -0
- package/materiais/bauhaus/tipografia/NumeroBauhaus.tsx +21 -0
- package/materiais/bauhaus/tipografia/TituloBauhaus.tsx +32 -0
- package/materiais/bauhaus/transicoes/Cena.tsx +36 -0
- package/materiais/bauhaus/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/brutalista/base.ts +71 -0
- package/materiais/brutalista/camera/CameraDeriva.tsx +37 -0
- package/materiais/brutalista/cores/paleta.json +25 -0
- package/materiais/brutalista/cores/paleta.png +0 -0
- package/materiais/brutalista/formas/BlocoSombra.tsx +18 -0
- package/materiais/brutalista/formas/CartaoFotoBruto.tsx +19 -0
- package/materiais/brutalista/formas/FitaAlerta.tsx +20 -0
- package/materiais/brutalista/formas/ListaBruta.tsx +23 -0
- package/materiais/brutalista/formas/MonoEnorme.tsx +43 -0
- package/materiais/brutalista/formas/QuadroCor.tsx +14 -0
- package/materiais/brutalista/formas/Terminal.tsx +25 -0
- package/materiais/brutalista/pecas.json +559 -0
- package/materiais/brutalista/referencia/analise.md +81 -0
- package/materiais/brutalista/referencia/quadro-1.png +0 -0
- package/materiais/brutalista/referencia/quadro-2.png +0 -0
- package/materiais/brutalista/referencia/quadro-3.png +0 -0
- package/materiais/brutalista/referencia/quadro-4.png +0 -0
- package/materiais/brutalista/referencia/referencia.mp4 +0 -0
- package/materiais/brutalista/regras.md +128 -0
- package/materiais/brutalista/sons/Som.tsx +38 -0
- package/materiais/brutalista/texturas/Fundo.tsx +9 -0
- package/materiais/brutalista/texturas/Particulas.tsx +22 -0
- package/materiais/brutalista/tipografia/AssinaturaMarca.tsx +21 -0
- package/materiais/brutalista/tipografia/ContadorGrande.tsx +21 -0
- package/materiais/brutalista/transicoes/Cena.tsx +41 -0
- package/materiais/brutalista/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/campos-de-cor/base.ts +87 -0
- package/materiais/campos-de-cor/camera/Camera.tsx +23 -0
- package/materiais/campos-de-cor/camera/CameraDeriva.tsx +37 -0
- package/materiais/campos-de-cor/cores/paleta.json +25 -0
- package/materiais/campos-de-cor/cores/paleta.png +0 -0
- package/materiais/campos-de-cor/formas/Asterisco.tsx +26 -0
- package/materiais/campos-de-cor/formas/CampoDeCor.tsx +39 -0
- package/materiais/campos-de-cor/formas/FormaGeometrica.tsx +37 -0
- package/materiais/campos-de-cor/formas/ListaRegua.tsx +30 -0
- package/materiais/campos-de-cor/pecas.json +534 -0
- package/materiais/campos-de-cor/referencia/analise.md +81 -0
- package/materiais/campos-de-cor/referencia/quadro-1.png +0 -0
- package/materiais/campos-de-cor/referencia/quadro-2.png +0 -0
- package/materiais/campos-de-cor/referencia/quadro-3.png +0 -0
- package/materiais/campos-de-cor/referencia/quadro-4.png +0 -0
- package/materiais/campos-de-cor/referencia/referencia.mp4 +0 -0
- package/materiais/campos-de-cor/regras.md +125 -0
- package/materiais/campos-de-cor/sons/Som.tsx +39 -0
- package/materiais/campos-de-cor/texturas/Fundo.tsx +11 -0
- package/materiais/campos-de-cor/texturas/Particulas.tsx +22 -0
- package/materiais/campos-de-cor/tipografia/AssinaturaMarca.tsx +18 -0
- package/materiais/campos-de-cor/tipografia/FitaDeTexto.tsx +24 -0
- package/materiais/campos-de-cor/tipografia/LegendaItalica.tsx +12 -0
- package/materiais/campos-de-cor/tipografia/PalavraGigante.tsx +44 -0
- package/materiais/campos-de-cor/transicoes/Cena.tsx +46 -0
- package/materiais/campos-de-cor/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/cartaz-cinetico/base.ts +72 -0
- package/materiais/cartaz-cinetico/camera/CameraDeriva.tsx +37 -0
- package/materiais/cartaz-cinetico/cores/paleta.json +26 -0
- package/materiais/cartaz-cinetico/cores/paleta.png +0 -0
- package/materiais/cartaz-cinetico/formas/CirculoPoster.tsx +22 -0
- package/materiais/cartaz-cinetico/formas/PilhaCartaz.tsx +40 -0
- package/materiais/cartaz-cinetico/formas/Selo.tsx +25 -0
- package/materiais/cartaz-cinetico/pecas.json +524 -0
- package/materiais/cartaz-cinetico/referencia/analise.md +83 -0
- package/materiais/cartaz-cinetico/referencia/quadro-1.png +0 -0
- package/materiais/cartaz-cinetico/referencia/quadro-2.png +0 -0
- package/materiais/cartaz-cinetico/referencia/quadro-3.png +0 -0
- package/materiais/cartaz-cinetico/referencia/quadro-4.png +0 -0
- package/materiais/cartaz-cinetico/referencia/referencia.mp4 +0 -0
- package/materiais/cartaz-cinetico/regras.md +131 -0
- package/materiais/cartaz-cinetico/sons/Som.tsx +38 -0
- package/materiais/cartaz-cinetico/texturas/Fundo.tsx +16 -0
- package/materiais/cartaz-cinetico/texturas/Particulas.tsx +22 -0
- package/materiais/cartaz-cinetico/tipografia/AssinaturaMarca.tsx +31 -0
- package/materiais/cartaz-cinetico/tipografia/CartazPalavra.tsx +40 -0
- package/materiais/cartaz-cinetico/tipografia/EcoPalavra.tsx +27 -0
- package/materiais/cartaz-cinetico/tipografia/RoletaPalavras.tsx +30 -0
- package/materiais/cartaz-cinetico/transicoes/Cena.tsx +41 -0
- package/materiais/cartaz-cinetico/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/colagem/base.ts +77 -0
- package/materiais/colagem/camera/Camera.tsx +21 -0
- package/materiais/colagem/camera/CameraDeriva.tsx +37 -0
- package/materiais/colagem/cores/paleta.json +30 -0
- package/materiais/colagem/cores/paleta.png +0 -0
- package/materiais/colagem/formas/FitaAdesiva.tsx +11 -0
- package/materiais/colagem/formas/FotoRasgada.tsx +26 -0
- package/materiais/colagem/formas/ListaRecortes.tsx +23 -0
- package/materiais/colagem/formas/NotaDatilografada.tsx +35 -0
- package/materiais/colagem/formas/RecorteForma.tsx +23 -0
- package/materiais/colagem/lib/rasgado.ts +16 -0
- package/materiais/colagem/pecas.json +547 -0
- package/materiais/colagem/referencia/analise.md +82 -0
- package/materiais/colagem/referencia/quadro-1.png +0 -0
- package/materiais/colagem/referencia/quadro-2.png +0 -0
- package/materiais/colagem/referencia/quadro-3.png +0 -0
- package/materiais/colagem/referencia/quadro-4.png +0 -0
- package/materiais/colagem/referencia/referencia.mp4 +0 -0
- package/materiais/colagem/regras.md +129 -0
- package/materiais/colagem/sons/Som.tsx +30 -0
- package/materiais/colagem/texturas/Fundo.tsx +16 -0
- package/materiais/colagem/texturas/Particulas.tsx +22 -0
- package/materiais/colagem/tipografia/AssinaturaMarca.tsx +17 -0
- package/materiais/colagem/tipografia/TituloRecorte.tsx +34 -0
- package/materiais/colagem/transicoes/Cena.tsx +36 -0
- package/materiais/colagem/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/contagem/base.ts +79 -0
- package/materiais/contagem/camera/CameraDeriva.tsx +37 -0
- package/materiais/contagem/cores/paleta.json +27 -0
- package/materiais/contagem/cores/paleta.png +0 -0
- package/materiais/contagem/formas/AnelTempo.tsx +36 -0
- package/materiais/contagem/formas/BarraDias.tsx +41 -0
- package/materiais/contagem/formas/CarimboData.tsx +37 -0
- package/materiais/contagem/formas/RelogioFlip.tsx +51 -0
- package/materiais/contagem/pecas.json +509 -0
- package/materiais/contagem/referencia/analise.md +85 -0
- package/materiais/contagem/referencia/quadro-1.png +0 -0
- package/materiais/contagem/referencia/quadro-2.png +0 -0
- package/materiais/contagem/referencia/quadro-3.png +0 -0
- package/materiais/contagem/referencia/quadro-4.png +0 -0
- package/materiais/contagem/referencia/referencia.mp4 +0 -0
- package/materiais/contagem/regras.md +134 -0
- package/materiais/contagem/sons/Som.tsx +41 -0
- package/materiais/contagem/texturas/Fundo.tsx +27 -0
- package/materiais/contagem/texturas/Particulas.tsx +22 -0
- package/materiais/contagem/tipografia/NumeroRolando.tsx +49 -0
- package/materiais/contagem/transicoes/Cena.tsx +39 -0
- package/materiais/contagem/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/convite-evento/base.ts +82 -0
- package/materiais/convite-evento/camera/CameraDeriva.tsx +37 -0
- package/materiais/convite-evento/cores/paleta.json +27 -0
- package/materiais/convite-evento/cores/paleta.png +0 -0
- package/materiais/convite-evento/formas/BotaoInscricao.tsx +36 -0
- package/materiais/convite-evento/formas/DataGigante.tsx +37 -0
- package/materiais/convite-evento/formas/IngressoBilhete.tsx +40 -0
- package/materiais/convite-evento/formas/LugarGigante.tsx +38 -0
- package/materiais/convite-evento/formas/SeloRotativo.tsx +32 -0
- package/materiais/convite-evento/pecas.json +511 -0
- package/materiais/convite-evento/referencia/analise.md +84 -0
- package/materiais/convite-evento/referencia/quadro-1.png +0 -0
- package/materiais/convite-evento/referencia/quadro-2.png +0 -0
- package/materiais/convite-evento/referencia/quadro-3.png +0 -0
- package/materiais/convite-evento/referencia/quadro-4.png +0 -0
- package/materiais/convite-evento/referencia/referencia.mp4 +0 -0
- package/materiais/convite-evento/regras.md +135 -0
- package/materiais/convite-evento/sons/Som.tsx +40 -0
- package/materiais/convite-evento/texturas/Fundo.tsx +30 -0
- package/materiais/convite-evento/texturas/Particulas.tsx +22 -0
- package/materiais/convite-evento/tipografia/TituloEvento.tsx +33 -0
- package/materiais/convite-evento/transicoes/Cena.tsx +39 -0
- package/materiais/convite-evento/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/corte-podcast/base.ts +82 -0
- package/materiais/corte-podcast/camera/CameraDeriva.tsx +37 -0
- package/materiais/corte-podcast/cores/paleta.json +28 -0
- package/materiais/corte-podcast/cores/paleta.png +0 -0
- package/materiais/corte-podcast/formas/BarraEpisodio.tsx +43 -0
- package/materiais/corte-podcast/formas/CartaoConvidado.tsx +32 -0
- package/materiais/corte-podcast/formas/OndaAudio.tsx +41 -0
- package/materiais/corte-podcast/formas/SeloEpisodio.tsx +33 -0
- package/materiais/corte-podcast/pecas.json +516 -0
- package/materiais/corte-podcast/referencia/analise.md +84 -0
- package/materiais/corte-podcast/referencia/quadro-1.png +0 -0
- package/materiais/corte-podcast/referencia/quadro-2.png +0 -0
- package/materiais/corte-podcast/referencia/quadro-3.png +0 -0
- package/materiais/corte-podcast/referencia/quadro-4.png +0 -0
- package/materiais/corte-podcast/referencia/referencia.mp4 +0 -0
- package/materiais/corte-podcast/regras.md +132 -0
- package/materiais/corte-podcast/sons/Som.tsx +40 -0
- package/materiais/corte-podcast/texturas/Fundo.tsx +27 -0
- package/materiais/corte-podcast/texturas/Particulas.tsx +22 -0
- package/materiais/corte-podcast/tipografia/CitacaoGrande.tsx +42 -0
- package/materiais/corte-podcast/tipografia/LegendaKaraoke.tsx +32 -0
- package/materiais/corte-podcast/transicoes/Cena.tsx +41 -0
- package/materiais/corte-podcast/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/cubos/base.ts +97 -0
- package/materiais/cubos/camera/CameraDeriva.tsx +37 -0
- package/materiais/cubos/cores/paleta.json +29 -0
- package/materiais/cubos/cores/paleta.png +0 -0
- package/materiais/cubos/formas/Cubo.tsx +40 -0
- package/materiais/cubos/formas/CuboGiratorio.tsx +37 -0
- package/materiais/cubos/formas/MontagemDeCubos.tsx +58 -0
- package/materiais/cubos/formas/PlacaBloco.tsx +29 -0
- package/materiais/cubos/formas/TorreDeCubos.tsx +39 -0
- package/materiais/cubos/pecas.json +477 -0
- package/materiais/cubos/referencia/analise.md +83 -0
- package/materiais/cubos/referencia/quadro-1.png +0 -0
- package/materiais/cubos/referencia/quadro-2.png +0 -0
- package/materiais/cubos/referencia/quadro-3.png +0 -0
- package/materiais/cubos/referencia/quadro-4.png +0 -0
- package/materiais/cubos/referencia/referencia.mp4 +0 -0
- package/materiais/cubos/regras.md +136 -0
- package/materiais/cubos/sons/Som.tsx +33 -0
- package/materiais/cubos/texturas/Fundo.tsx +15 -0
- package/materiais/cubos/texturas/Particulas.tsx +22 -0
- package/materiais/cubos/tipografia/AssinaturaMarca.tsx +29 -0
- package/materiais/cubos/transicoes/Cena.tsx +48 -0
- package/materiais/cubos/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/dashboard-dados/base.ts +87 -0
- package/materiais/dashboard-dados/camera/Camera.tsx +23 -0
- package/materiais/dashboard-dados/camera/CameraDeriva.tsx +37 -0
- package/materiais/dashboard-dados/cores/paleta.json +30 -0
- package/materiais/dashboard-dados/cores/paleta.png +0 -0
- package/materiais/dashboard-dados/formas/BarrasCrescendo.tsx +27 -0
- package/materiais/dashboard-dados/formas/LinhaTendencia.tsx +29 -0
- package/materiais/dashboard-dados/formas/RankingBarras.tsx +27 -0
- package/materiais/dashboard-dados/formas/RoscaDados.tsx +39 -0
- package/materiais/dashboard-dados/pecas.json +490 -0
- package/materiais/dashboard-dados/referencia/analise.md +84 -0
- package/materiais/dashboard-dados/referencia/quadro-1.png +0 -0
- package/materiais/dashboard-dados/referencia/quadro-2.png +0 -0
- package/materiais/dashboard-dados/referencia/quadro-3.png +0 -0
- package/materiais/dashboard-dados/referencia/quadro-4.png +0 -0
- package/materiais/dashboard-dados/referencia/referencia.mp4 +0 -0
- package/materiais/dashboard-dados/regras.md +130 -0
- package/materiais/dashboard-dados/sons/Som.tsx +39 -0
- package/materiais/dashboard-dados/texturas/Fundo.tsx +12 -0
- package/materiais/dashboard-dados/texturas/Particulas.tsx +22 -0
- package/materiais/dashboard-dados/tipografia/AssinaturaMarca.tsx +19 -0
- package/materiais/dashboard-dados/tipografia/NumeroGigante.tsx +21 -0
- package/materiais/dashboard-dados/transicoes/Cena.tsx +46 -0
- package/materiais/dashboard-dados/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/depoimento/base.ts +83 -0
- package/materiais/depoimento/camera/CameraDeriva.tsx +37 -0
- package/materiais/depoimento/cores/paleta.json +29 -0
- package/materiais/depoimento/cores/paleta.png +0 -0
- package/materiais/depoimento/formas/Avatar.tsx +37 -0
- package/materiais/depoimento/formas/CartaoDepoimento.tsx +69 -0
- package/materiais/depoimento/formas/FaixaAvatares.tsx +41 -0
- package/materiais/depoimento/formas/NotaGigante.tsx +38 -0
- package/materiais/depoimento/formas/PilhaCartoes.tsx +37 -0
- package/materiais/depoimento/formas/SeloVerificado.tsx +29 -0
- package/materiais/depoimento/pecas.json +548 -0
- package/materiais/depoimento/referencia/analise.md +84 -0
- package/materiais/depoimento/referencia/quadro-1.png +0 -0
- package/materiais/depoimento/referencia/quadro-2.png +0 -0
- package/materiais/depoimento/referencia/quadro-3.png +0 -0
- package/materiais/depoimento/referencia/quadro-4.png +0 -0
- package/materiais/depoimento/referencia/referencia.mp4 +0 -0
- package/materiais/depoimento/regras.md +135 -0
- package/materiais/depoimento/sons/Som.tsx +41 -0
- package/materiais/depoimento/texturas/Estrelas.tsx +34 -0
- package/materiais/depoimento/texturas/Fundo.tsx +23 -0
- package/materiais/depoimento/texturas/Particulas.tsx +22 -0
- package/materiais/depoimento/transicoes/Cena.tsx +39 -0
- package/materiais/depoimento/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/infografico/base.ts +80 -0
- package/materiais/infografico/camera/CameraDeriva.tsx +37 -0
- package/materiais/infografico/cores/paleta.json +28 -0
- package/materiais/infografico/cores/paleta.png +0 -0
- package/materiais/infografico/formas/Anotacao.tsx +34 -0
- package/materiais/infografico/formas/CadeiaPassos.tsx +49 -0
- package/materiais/infografico/formas/GraficoBarras.tsx +41 -0
- package/materiais/infografico/formas/Icone.tsx +35 -0
- package/materiais/infografico/formas/NoProcesso.tsx +33 -0
- package/materiais/infografico/formas/SetaCurva.tsx +33 -0
- package/materiais/infografico/pecas.json +540 -0
- package/materiais/infografico/referencia/analise.md +84 -0
- package/materiais/infografico/referencia/quadro-1.png +0 -0
- package/materiais/infografico/referencia/quadro-2.png +0 -0
- package/materiais/infografico/referencia/quadro-3.png +0 -0
- package/materiais/infografico/referencia/quadro-4.png +0 -0
- package/materiais/infografico/referencia/referencia.mp4 +0 -0
- package/materiais/infografico/regras.md +132 -0
- package/materiais/infografico/sons/Som.tsx +40 -0
- package/materiais/infografico/texturas/Fundo.tsx +23 -0
- package/materiais/infografico/texturas/Particulas.tsx +22 -0
- package/materiais/infografico/tipografia/NumeroDestaque.tsx +35 -0
- package/materiais/infografico/transicoes/Cena.tsx +39 -0
- package/materiais/infografico/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/isometrico/base.ts +86 -0
- package/materiais/isometrico/camera/Camera.tsx +23 -0
- package/materiais/isometrico/camera/CameraDeriva.tsx +37 -0
- package/materiais/isometrico/cores/paleta.json +29 -0
- package/materiais/isometrico/cores/paleta.png +0 -0
- package/materiais/isometrico/formas/BlocosMontando.tsx +36 -0
- package/materiais/isometrico/formas/CidadeDeDados.tsx +33 -0
- package/materiais/isometrico/formas/RedeDeBlocos.tsx +41 -0
- package/materiais/isometrico/pecas.json +503 -0
- package/materiais/isometrico/referencia/analise.md +83 -0
- package/materiais/isometrico/referencia/quadro-1.png +0 -0
- package/materiais/isometrico/referencia/quadro-2.png +0 -0
- package/materiais/isometrico/referencia/quadro-3.png +0 -0
- package/materiais/isometrico/referencia/quadro-4.png +0 -0
- package/materiais/isometrico/referencia/referencia.mp4 +0 -0
- package/materiais/isometrico/regras.md +125 -0
- package/materiais/isometrico/sons/Som.tsx +39 -0
- package/materiais/isometrico/texturas/Fundo.tsx +13 -0
- package/materiais/isometrico/texturas/Particulas.tsx +22 -0
- package/materiais/isometrico/tipografia/AssinaturaMarca.tsx +24 -0
- package/materiais/isometrico/tipografia/LegendaPlaca.tsx +18 -0
- package/materiais/isometrico/tipografia/TextoNoChao.tsx +28 -0
- package/materiais/isometrico/transicoes/Cena.tsx +46 -0
- package/materiais/isometrico/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/jornal/base.ts +76 -0
- package/materiais/jornal/camera/CameraDeriva.tsx +37 -0
- package/materiais/jornal/cores/paleta.json +27 -0
- package/materiais/jornal/cores/paleta.png +0 -0
- package/materiais/jornal/formas/Cabecalho.tsx +21 -0
- package/materiais/jornal/formas/Carimbo.tsx +18 -0
- package/materiais/jornal/formas/Colunas.tsx +24 -0
- package/materiais/jornal/formas/FotoMeiaTinta.tsx +20 -0
- package/materiais/jornal/formas/JornalGirando.tsx +27 -0
- package/materiais/jornal/formas/Ticker.tsx +19 -0
- package/materiais/jornal/pecas.json +535 -0
- package/materiais/jornal/referencia/analise.md +81 -0
- package/materiais/jornal/referencia/quadro-1.png +0 -0
- package/materiais/jornal/referencia/quadro-2.png +0 -0
- package/materiais/jornal/referencia/quadro-3.png +0 -0
- package/materiais/jornal/referencia/quadro-4.png +0 -0
- package/materiais/jornal/referencia/referencia.mp4 +0 -0
- package/materiais/jornal/regras.md +131 -0
- package/materiais/jornal/sons/Som.tsx +38 -0
- package/materiais/jornal/texturas/Fundo.tsx +18 -0
- package/materiais/jornal/texturas/Particulas.tsx +22 -0
- package/materiais/jornal/tipografia/AssinaturaMarca.tsx +25 -0
- package/materiais/jornal/tipografia/Manchete.tsx +30 -0
- package/materiais/jornal/transicoes/Cena.tsx +41 -0
- package/materiais/jornal/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/legenda-viva/base.ts +73 -0
- package/materiais/legenda-viva/camera/CameraDeriva.tsx +37 -0
- package/materiais/legenda-viva/cores/paleta.json +27 -0
- package/materiais/legenda-viva/cores/paleta.png +0 -0
- package/materiais/legenda-viva/formas/ChipTema.tsx +19 -0
- package/materiais/legenda-viva/formas/OndaVoz.tsx +23 -0
- package/materiais/legenda-viva/formas/QuadroFalante.tsx +17 -0
- package/materiais/legenda-viva/pecas.json +503 -0
- package/materiais/legenda-viva/referencia/analise.md +79 -0
- package/materiais/legenda-viva/referencia/quadro-1.png +0 -0
- package/materiais/legenda-viva/referencia/quadro-2.png +0 -0
- package/materiais/legenda-viva/referencia/quadro-3.png +0 -0
- package/materiais/legenda-viva/referencia/quadro-4.png +0 -0
- package/materiais/legenda-viva/referencia/referencia.mp4 +0 -0
- package/materiais/legenda-viva/regras.md +130 -0
- package/materiais/legenda-viva/sons/Som.tsx +38 -0
- package/materiais/legenda-viva/texturas/Fundo.tsx +6 -0
- package/materiais/legenda-viva/texturas/Particulas.tsx +22 -0
- package/materiais/legenda-viva/tipografia/AssinaturaMarca.tsx +29 -0
- package/materiais/legenda-viva/tipografia/LegendaCaixa.tsx +36 -0
- package/materiais/legenda-viva/tipografia/LegendaPalavra.tsx +32 -0
- package/materiais/legenda-viva/tipografia/PalavraGigante.tsx +18 -0
- package/materiais/legenda-viva/transicoes/Cena.tsx +41 -0
- package/materiais/legenda-viva/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/luxo/base.ts +85 -0
- package/materiais/luxo/camera/CameraDeriva.tsx +37 -0
- package/materiais/luxo/cores/paleta.json +28 -0
- package/materiais/luxo/cores/paleta.png +0 -0
- package/materiais/luxo/formas/ConviteOuro.tsx +34 -0
- package/materiais/luxo/formas/LinhaOuro.tsx +24 -0
- package/materiais/luxo/formas/MolduraArco.tsx +36 -0
- package/materiais/luxo/formas/Monograma.tsx +35 -0
- package/materiais/luxo/pecas.json +505 -0
- package/materiais/luxo/referencia/analise.md +82 -0
- package/materiais/luxo/referencia/quadro-1.png +0 -0
- package/materiais/luxo/referencia/quadro-2.png +0 -0
- package/materiais/luxo/referencia/quadro-3.png +0 -0
- package/materiais/luxo/referencia/quadro-4.png +0 -0
- package/materiais/luxo/referencia/referencia.mp4 +0 -0
- package/materiais/luxo/regras.md +132 -0
- package/materiais/luxo/sons/Som.tsx +40 -0
- package/materiais/luxo/texturas/Fundo.tsx +26 -0
- package/materiais/luxo/texturas/Particulas.tsx +22 -0
- package/materiais/luxo/tipografia/LegendaFina.tsx +25 -0
- package/materiais/luxo/tipografia/TituloSerifa.tsx +35 -0
- package/materiais/luxo/transicoes/Cena.tsx +36 -0
- package/materiais/luxo/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/mapa/base.ts +89 -0
- package/materiais/mapa/camera/CameraDeriva.tsx +37 -0
- package/materiais/mapa/cores/paleta.json +33 -0
- package/materiais/mapa/cores/paleta.png +0 -0
- package/materiais/mapa/formas/CartaoEndereco.tsx +40 -0
- package/materiais/mapa/formas/ChipTempo.tsx +29 -0
- package/materiais/mapa/formas/MapaBase.tsx +63 -0
- package/materiais/mapa/formas/Pino.tsx +38 -0
- package/materiais/mapa/formas/RotaAnimada.tsx +38 -0
- package/materiais/mapa/pecas.json +529 -0
- package/materiais/mapa/referencia/analise.md +85 -0
- package/materiais/mapa/referencia/quadro-1.png +0 -0
- package/materiais/mapa/referencia/quadro-2.png +0 -0
- package/materiais/mapa/referencia/quadro-3.png +0 -0
- package/materiais/mapa/referencia/quadro-4.png +0 -0
- package/materiais/mapa/referencia/referencia.mp4 +0 -0
- package/materiais/mapa/regras.md +135 -0
- package/materiais/mapa/sons/Som.tsx +41 -0
- package/materiais/mapa/texturas/Fundo.tsx +25 -0
- package/materiais/mapa/texturas/Particulas.tsx +22 -0
- package/materiais/mapa/tipografia/TituloLocal.tsx +38 -0
- package/materiais/mapa/transicoes/Cena.tsx +41 -0
- package/materiais/mapa/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/massinha/base.ts +79 -0
- package/materiais/massinha/camera/Camera.tsx +21 -0
- package/materiais/massinha/camera/CameraDeriva.tsx +37 -0
- package/materiais/massinha/cores/paleta.json +32 -0
- package/materiais/massinha/cores/paleta.png +0 -0
- package/materiais/massinha/formas/BichinhoMassa.tsx +30 -0
- package/materiais/massinha/formas/BolasMassa.tsx +25 -0
- package/materiais/massinha/formas/FormaMassa.tsx +23 -0
- package/materiais/massinha/formas/ListaMassa.tsx +19 -0
- package/materiais/massinha/formas/Overlay.tsx +11 -0
- package/materiais/massinha/formas/PlacaMassa.tsx +24 -0
- package/materiais/massinha/pecas.json +544 -0
- package/materiais/massinha/referencia/analise.md +81 -0
- package/materiais/massinha/referencia/quadro-1.png +0 -0
- package/materiais/massinha/referencia/quadro-2.png +0 -0
- package/materiais/massinha/referencia/quadro-3.png +0 -0
- package/materiais/massinha/referencia/quadro-4.png +0 -0
- package/materiais/massinha/referencia/referencia.mp4 +0 -0
- package/materiais/massinha/regras.md +129 -0
- package/materiais/massinha/sons/Som.tsx +30 -0
- package/materiais/massinha/texturas/Fundo.tsx +12 -0
- package/materiais/massinha/texturas/Particulas.tsx +22 -0
- package/materiais/massinha/tipografia/AssinaturaMarca.tsx +20 -0
- package/materiais/massinha/tipografia/TituloMassa.tsx +31 -0
- package/materiais/massinha/transicoes/Cena.tsx +36 -0
- package/materiais/massinha/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/memphis/base.ts +78 -0
- package/materiais/memphis/camera/Camera.tsx +21 -0
- package/materiais/memphis/camera/CameraDeriva.tsx +37 -0
- package/materiais/memphis/cores/paleta.json +31 -0
- package/materiais/memphis/cores/paleta.png +0 -0
- package/materiais/memphis/formas/CartaoMemphis.tsx +16 -0
- package/materiais/memphis/formas/FitaMarquee.tsx +21 -0
- package/materiais/memphis/formas/FormasMemphis.tsx +46 -0
- package/materiais/memphis/formas/ListaPilulas.tsx +17 -0
- package/materiais/memphis/formas/Overlay.tsx +23 -0
- package/materiais/memphis/pecas.json +544 -0
- package/materiais/memphis/referencia/analise.md +82 -0
- package/materiais/memphis/referencia/quadro-1.png +0 -0
- package/materiais/memphis/referencia/quadro-2.png +0 -0
- package/materiais/memphis/referencia/quadro-3.png +0 -0
- package/materiais/memphis/referencia/quadro-4.png +0 -0
- package/materiais/memphis/referencia/referencia.mp4 +0 -0
- package/materiais/memphis/regras.md +130 -0
- package/materiais/memphis/sons/Som.tsx +30 -0
- package/materiais/memphis/texturas/Fundo.tsx +15 -0
- package/materiais/memphis/texturas/Particulas.tsx +22 -0
- package/materiais/memphis/tipografia/AssinaturaMarca.tsx +20 -0
- package/materiais/memphis/tipografia/NumeroGigante.tsx +19 -0
- package/materiais/memphis/tipografia/TituloMemphis.tsx +28 -0
- package/materiais/memphis/transicoes/Cena.tsx +36 -0
- package/materiais/memphis/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/metal-liquido/base.ts +94 -0
- package/materiais/metal-liquido/camera/CameraDeriva.tsx +37 -0
- package/materiais/metal-liquido/cores/paleta.json +30 -0
- package/materiais/metal-liquido/cores/paleta.png +0 -0
- package/materiais/metal-liquido/formas/AnelCromo.tsx +28 -0
- package/materiais/metal-liquido/formas/BolhasCromadas.tsx +53 -0
- package/materiais/metal-liquido/formas/EsferaCromo.tsx +32 -0
- package/materiais/metal-liquido/formas/PilulaCromo.tsx +23 -0
- package/materiais/metal-liquido/pecas.json +469 -0
- package/materiais/metal-liquido/referencia/analise.md +84 -0
- package/materiais/metal-liquido/referencia/quadro-1.png +0 -0
- package/materiais/metal-liquido/referencia/quadro-2.png +0 -0
- package/materiais/metal-liquido/referencia/quadro-3.png +0 -0
- package/materiais/metal-liquido/referencia/quadro-4.png +0 -0
- package/materiais/metal-liquido/referencia/referencia.mp4 +0 -0
- package/materiais/metal-liquido/regras.md +135 -0
- package/materiais/metal-liquido/sons/Som.tsx +33 -0
- package/materiais/metal-liquido/texturas/Fundo.tsx +20 -0
- package/materiais/metal-liquido/texturas/Particulas.tsx +22 -0
- package/materiais/metal-liquido/tipografia/AssinaturaMarca.tsx +26 -0
- package/materiais/metal-liquido/tipografia/TituloCromo.tsx +32 -0
- package/materiais/metal-liquido/transicoes/Cena.tsx +48 -0
- package/materiais/metal-liquido/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/minimal/base.ts +80 -0
- package/materiais/minimal/camera/CameraDeriva.tsx +37 -0
- package/materiais/minimal/cores/paleta.json +26 -0
- package/materiais/minimal/cores/paleta.png +0 -0
- package/materiais/minimal/formas/FormaMorph.tsx +44 -0
- package/materiais/minimal/formas/LinhaFina.tsx +24 -0
- package/materiais/minimal/formas/PontoMovel.tsx +27 -0
- package/materiais/minimal/pecas.json +505 -0
- package/materiais/minimal/referencia/analise.md +84 -0
- package/materiais/minimal/referencia/quadro-1.png +0 -0
- package/materiais/minimal/referencia/quadro-2.png +0 -0
- package/materiais/minimal/referencia/quadro-3.png +0 -0
- package/materiais/minimal/referencia/quadro-4.png +0 -0
- package/materiais/minimal/referencia/referencia.mp4 +0 -0
- package/materiais/minimal/regras.md +127 -0
- package/materiais/minimal/sons/Som.tsx +40 -0
- package/materiais/minimal/texturas/Fundo.tsx +20 -0
- package/materiais/minimal/texturas/Particulas.tsx +22 -0
- package/materiais/minimal/tipografia/FraseUnica.tsx +33 -0
- package/materiais/minimal/tipografia/NumeroSolo.tsx +33 -0
- package/materiais/minimal/tipografia/RodapeMinimal.tsx +26 -0
- package/materiais/minimal/transicoes/Cena.tsx +39 -0
- package/materiais/minimal/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/neon-cidade/base.ts +100 -0
- package/materiais/neon-cidade/camera/CameraDeriva.tsx +37 -0
- package/materiais/neon-cidade/cores/paleta.json +29 -0
- package/materiais/neon-cidade/cores/paleta.png +0 -0
- package/materiais/neon-cidade/formas/CaixaLuminosa.tsx +40 -0
- package/materiais/neon-cidade/formas/FormaNeon.tsx +42 -0
- package/materiais/neon-cidade/formas/Horizonte.tsx +34 -0
- package/materiais/neon-cidade/formas/LetreiroNeon.tsx +46 -0
- package/materiais/neon-cidade/pecas.json +464 -0
- package/materiais/neon-cidade/referencia/analise.md +84 -0
- package/materiais/neon-cidade/referencia/quadro-1.png +0 -0
- package/materiais/neon-cidade/referencia/quadro-2.png +0 -0
- package/materiais/neon-cidade/referencia/quadro-3.png +0 -0
- package/materiais/neon-cidade/referencia/quadro-4.png +0 -0
- package/materiais/neon-cidade/referencia/referencia.mp4 +0 -0
- package/materiais/neon-cidade/regras.md +137 -0
- package/materiais/neon-cidade/sons/Som.tsx +33 -0
- package/materiais/neon-cidade/texturas/Chuva.tsx +23 -0
- package/materiais/neon-cidade/texturas/Fundo.tsx +18 -0
- package/materiais/neon-cidade/texturas/Particulas.tsx +22 -0
- package/materiais/neon-cidade/tipografia/AssinaturaMarca.tsx +24 -0
- package/materiais/neon-cidade/transicoes/Cena.tsx +48 -0
- package/materiais/neon-cidade/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/notion-editorial/base.ts +87 -0
- package/materiais/notion-editorial/camera/Camera.tsx +23 -0
- package/materiais/notion-editorial/camera/CameraDeriva.tsx +37 -0
- package/materiais/notion-editorial/cores/paleta.json +28 -0
- package/materiais/notion-editorial/cores/paleta.png +0 -0
- package/materiais/notion-editorial/formas/BlocoNota.tsx +38 -0
- package/materiais/notion-editorial/formas/Diagrama.tsx +29 -0
- package/materiais/notion-editorial/formas/PassosNumerados.tsx +23 -0
- package/materiais/notion-editorial/formas/RabiscoIcone.tsx +33 -0
- package/materiais/notion-editorial/pecas.json +496 -0
- package/materiais/notion-editorial/referencia/analise.md +83 -0
- package/materiais/notion-editorial/referencia/quadro-1.png +0 -0
- package/materiais/notion-editorial/referencia/quadro-2.png +0 -0
- package/materiais/notion-editorial/referencia/quadro-3.png +0 -0
- package/materiais/notion-editorial/referencia/quadro-4.png +0 -0
- package/materiais/notion-editorial/referencia/referencia.mp4 +0 -0
- package/materiais/notion-editorial/regras.md +126 -0
- package/materiais/notion-editorial/sons/Som.tsx +39 -0
- package/materiais/notion-editorial/texturas/Fundo.tsx +12 -0
- package/materiais/notion-editorial/texturas/Particulas.tsx +22 -0
- package/materiais/notion-editorial/tipografia/AssinaturaMarca.tsx +20 -0
- package/materiais/notion-editorial/tipografia/TextoSerifa.tsx +53 -0
- package/materiais/notion-editorial/transicoes/Cena.tsx +46 -0
- package/materiais/notion-editorial/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/papel-recortado/base.ts +51 -0
- package/materiais/papel-recortado/camera/Camera.tsx +28 -0
- package/materiais/papel-recortado/camera/CameraDeriva.tsx +37 -0
- package/materiais/papel-recortado/cores/paleta.json +28 -0
- package/materiais/papel-recortado/cores/paleta.png +0 -0
- package/materiais/papel-recortado/formas/CamadaPapel.tsx +81 -0
- package/materiais/papel-recortado/formas/CartaoCamadas.tsx +38 -0
- package/materiais/papel-recortado/formas/EtiquetaPapel.tsx +40 -0
- package/materiais/papel-recortado/formas/Fita.tsx +21 -0
- package/materiais/papel-recortado/formas/FolhaPopUp.tsx +49 -0
- package/materiais/papel-recortado/formas/MolduraPapel.tsx +12 -0
- package/materiais/papel-recortado/pecas.json +545 -0
- package/materiais/papel-recortado/referencia/analise.md +82 -0
- package/materiais/papel-recortado/referencia/quadro-1.png +0 -0
- package/materiais/papel-recortado/referencia/quadro-2.png +0 -0
- package/materiais/papel-recortado/referencia/quadro-3.png +0 -0
- package/materiais/papel-recortado/referencia/quadro-4.png +0 -0
- package/materiais/papel-recortado/referencia/referencia.mp4 +0 -0
- package/materiais/papel-recortado/regras.md +117 -0
- package/materiais/papel-recortado/sons/Som.tsx +30 -0
- package/materiais/papel-recortado/texturas/Fundo.tsx +10 -0
- package/materiais/papel-recortado/texturas/Particulas.tsx +22 -0
- package/materiais/papel-recortado/tipografia/LetrasRecortadas.tsx +48 -0
- package/materiais/papel-recortado/transicoes/Cena.tsx +29 -0
- package/materiais/papel-recortado/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/pixel/base.ts +79 -0
- package/materiais/pixel/camera/Camera.tsx +21 -0
- package/materiais/pixel/camera/CameraDeriva.tsx +37 -0
- package/materiais/pixel/cores/paleta.json +32 -0
- package/materiais/pixel/cores/paleta.png +0 -0
- package/materiais/pixel/formas/CaixaDialogo.tsx +22 -0
- package/materiais/pixel/formas/HudPlacar.tsx +19 -0
- package/materiais/pixel/formas/MenuPixel.tsx +19 -0
- package/materiais/pixel/formas/Overlay.tsx +14 -0
- package/materiais/pixel/formas/Sprite.tsx +33 -0
- package/materiais/pixel/pecas.json +543 -0
- package/materiais/pixel/referencia/analise.md +82 -0
- package/materiais/pixel/referencia/quadro-1.png +0 -0
- package/materiais/pixel/referencia/quadro-2.png +0 -0
- package/materiais/pixel/referencia/quadro-3.png +0 -0
- package/materiais/pixel/referencia/quadro-4.png +0 -0
- package/materiais/pixel/referencia/referencia.mp4 +0 -0
- package/materiais/pixel/regras.md +129 -0
- package/materiais/pixel/sons/Som.tsx +30 -0
- package/materiais/pixel/texturas/ChuvaDeSprites.tsx +15 -0
- package/materiais/pixel/texturas/Fundo.tsx +23 -0
- package/materiais/pixel/texturas/Particulas.tsx +22 -0
- package/materiais/pixel/tipografia/AssinaturaMarca.tsx +18 -0
- package/materiais/pixel/tipografia/TituloPixel.tsx +31 -0
- package/materiais/pixel/transicoes/Cena.tsx +36 -0
- package/materiais/pixel/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/pontos-3d/base.ts +92 -0
- package/materiais/pontos-3d/camera/CameraDeriva.tsx +37 -0
- package/materiais/pontos-3d/cores/paleta.json +28 -0
- package/materiais/pontos-3d/cores/paleta.png +0 -0
- package/materiais/pontos-3d/formas/NuvemDePontos.tsx +84 -0
- package/materiais/pontos-3d/formas/RotuloPonto.tsx +32 -0
- package/materiais/pontos-3d/pecas.json +481 -0
- package/materiais/pontos-3d/referencia/analise.md +85 -0
- package/materiais/pontos-3d/referencia/quadro-1.png +0 -0
- package/materiais/pontos-3d/referencia/quadro-2.png +0 -0
- package/materiais/pontos-3d/referencia/quadro-3.png +0 -0
- package/materiais/pontos-3d/referencia/quadro-4.png +0 -0
- package/materiais/pontos-3d/referencia/referencia.mp4 +0 -0
- package/materiais/pontos-3d/regras.md +136 -0
- package/materiais/pontos-3d/sons/Som.tsx +33 -0
- package/materiais/pontos-3d/texturas/Fundo.tsx +20 -0
- package/materiais/pontos-3d/texturas/Particulas.tsx +22 -0
- package/materiais/pontos-3d/tipografia/AssinaturaMarca.tsx +23 -0
- package/materiais/pontos-3d/tipografia/Contador.tsx +32 -0
- package/materiais/pontos-3d/tipografia/TextoDePontos.tsx +55 -0
- package/materiais/pontos-3d/tipografia/TituloSora.tsx +36 -0
- package/materiais/pontos-3d/transicoes/Cena.tsx +48 -0
- package/materiais/pontos-3d/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/produto-3d/base.ts +109 -0
- package/materiais/produto-3d/camera/Camera.tsx +23 -0
- package/materiais/produto-3d/camera/CameraDeriva.tsx +37 -0
- package/materiais/produto-3d/cores/paleta.json +31 -0
- package/materiais/produto-3d/cores/paleta.png +0 -0
- package/materiais/produto-3d/formas/Produto3D.tsx +131 -0
- package/materiais/produto-3d/lib/produto3d-apoio.ts +21 -0
- package/materiais/produto-3d/pecas.json +516 -0
- package/materiais/produto-3d/referencia/analise.md +83 -0
- package/materiais/produto-3d/referencia/quadro-1.png +0 -0
- package/materiais/produto-3d/referencia/quadro-2.png +0 -0
- package/materiais/produto-3d/referencia/quadro-3.png +0 -0
- package/materiais/produto-3d/referencia/quadro-4.png +0 -0
- package/materiais/produto-3d/referencia/referencia.mp4 +0 -0
- package/materiais/produto-3d/regras.md +128 -0
- package/materiais/produto-3d/sons/Som.tsx +39 -0
- package/materiais/produto-3d/texturas/Fundo.tsx +45 -0
- package/materiais/produto-3d/texturas/Particulas.tsx +22 -0
- package/materiais/produto-3d/tipografia/AssinaturaMarca.tsx +28 -0
- package/materiais/produto-3d/tipografia/NumeroDestaque.tsx +35 -0
- package/materiais/produto-3d/tipografia/RotuloChamada.tsx +43 -0
- package/materiais/produto-3d/tipografia/TituloMinimo.tsx +45 -0
- package/materiais/produto-3d/transicoes/Cena.tsx +55 -0
- package/materiais/produto-3d/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/produto-3d/transicoes/VarreduraLuz.tsx +22 -0
- package/materiais/quadro-giz/base.ts +78 -0
- package/materiais/quadro-giz/camera/Camera.tsx +21 -0
- package/materiais/quadro-giz/camera/CameraDeriva.tsx +37 -0
- package/materiais/quadro-giz/cores/paleta.json +31 -0
- package/materiais/quadro-giz/cores/paleta.png +0 -0
- package/materiais/quadro-giz/formas/ApagadorVarrendo.tsx +32 -0
- package/materiais/quadro-giz/formas/CartaoGiz.tsx +25 -0
- package/materiais/quadro-giz/formas/ContaNoQuadro.tsx +34 -0
- package/materiais/quadro-giz/formas/DesenhoGiz.tsx +29 -0
- package/materiais/quadro-giz/formas/ListaGiz.tsx +21 -0
- package/materiais/quadro-giz/formas/Overlay.tsx +12 -0
- package/materiais/quadro-giz/lib/traco.ts +9 -0
- package/materiais/quadro-giz/pecas.json +546 -0
- package/materiais/quadro-giz/referencia/analise.md +82 -0
- package/materiais/quadro-giz/referencia/quadro-1.png +0 -0
- package/materiais/quadro-giz/referencia/quadro-2.png +0 -0
- package/materiais/quadro-giz/referencia/quadro-3.png +0 -0
- package/materiais/quadro-giz/referencia/quadro-4.png +0 -0
- package/materiais/quadro-giz/referencia/referencia.mp4 +0 -0
- package/materiais/quadro-giz/regras.md +132 -0
- package/materiais/quadro-giz/sons/Som.tsx +30 -0
- package/materiais/quadro-giz/texturas/Fundo.tsx +21 -0
- package/materiais/quadro-giz/texturas/Particulas.tsx +22 -0
- package/materiais/quadro-giz/tipografia/AssinaturaMarca.tsx +20 -0
- package/materiais/quadro-giz/tipografia/TituloGiz.tsx +29 -0
- package/materiais/quadro-giz/transicoes/Cena.tsx +36 -0
- package/materiais/quadro-giz/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/rabisco/base.ts +76 -0
- package/materiais/rabisco/camera/Camera.tsx +21 -0
- package/materiais/rabisco/camera/CameraDeriva.tsx +37 -0
- package/materiais/rabisco/cores/paleta.json +29 -0
- package/materiais/rabisco/cores/paleta.png +0 -0
- package/materiais/rabisco/formas/Bonequinho.tsx +31 -0
- package/materiais/rabisco/formas/CartaoRabiscado.tsx +27 -0
- package/materiais/rabisco/formas/ListaRabiscada.tsx +23 -0
- package/materiais/rabisco/formas/TracoDesenhando.tsx +31 -0
- package/materiais/rabisco/lib/traco.ts +10 -0
- package/materiais/rabisco/pecas.json +520 -0
- package/materiais/rabisco/referencia/analise.md +82 -0
- package/materiais/rabisco/referencia/quadro-1.png +0 -0
- package/materiais/rabisco/referencia/quadro-2.png +0 -0
- package/materiais/rabisco/referencia/quadro-3.png +0 -0
- package/materiais/rabisco/referencia/quadro-4.png +0 -0
- package/materiais/rabisco/referencia/referencia.mp4 +0 -0
- package/materiais/rabisco/regras.md +126 -0
- package/materiais/rabisco/sons/Som.tsx +30 -0
- package/materiais/rabisco/texturas/Fundo.tsx +17 -0
- package/materiais/rabisco/texturas/Particulas.tsx +22 -0
- package/materiais/rabisco/tipografia/AssinaturaMarca.tsx +21 -0
- package/materiais/rabisco/tipografia/TituloRabisco.tsx +28 -0
- package/materiais/rabisco/transicoes/Cena.tsx +36 -0
- package/materiais/rabisco/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/retro-70/base.ts +73 -0
- package/materiais/retro-70/camera/CameraDeriva.tsx +37 -0
- package/materiais/retro-70/cores/paleta.json +27 -0
- package/materiais/retro-70/cores/paleta.png +0 -0
- package/materiais/retro-70/formas/ArcoListras.tsx +25 -0
- package/materiais/retro-70/formas/CartaoData.tsx +24 -0
- package/materiais/retro-70/formas/FaixaOnda.tsx +27 -0
- package/materiais/retro-70/formas/Flor70.tsx +25 -0
- package/materiais/retro-70/formas/FotoArredondada.tsx +19 -0
- package/materiais/retro-70/formas/RaiosDeSol.tsx +27 -0
- package/materiais/retro-70/pecas.json +533 -0
- package/materiais/retro-70/referencia/analise.md +81 -0
- package/materiais/retro-70/referencia/quadro-1.png +0 -0
- package/materiais/retro-70/referencia/quadro-2.png +0 -0
- package/materiais/retro-70/referencia/quadro-3.png +0 -0
- package/materiais/retro-70/referencia/quadro-4.png +0 -0
- package/materiais/retro-70/referencia/referencia.mp4 +0 -0
- package/materiais/retro-70/regras.md +132 -0
- package/materiais/retro-70/sons/Som.tsx +38 -0
- package/materiais/retro-70/texturas/Fundo.tsx +11 -0
- package/materiais/retro-70/texturas/Particulas.tsx +22 -0
- package/materiais/retro-70/tipografia/AssinaturaMarca.tsx +21 -0
- package/materiais/retro-70/tipografia/TituloGordo.tsx +28 -0
- package/materiais/retro-70/transicoes/Cena.tsx +41 -0
- package/materiais/retro-70/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/revista/base.ts +76 -0
- package/materiais/revista/camera/CameraDeriva.tsx +37 -0
- package/materiais/revista/cores/paleta.json +27 -0
- package/materiais/revista/cores/paleta.png +0 -0
- package/materiais/revista/formas/ColagemFotos.tsx +22 -0
- package/materiais/revista/formas/Folio.tsx +19 -0
- package/materiais/revista/formas/FotoSangrando.tsx +24 -0
- package/materiais/revista/formas/PaginaDupla.tsx +36 -0
- package/materiais/revista/pecas.json +506 -0
- package/materiais/revista/referencia/analise.md +80 -0
- package/materiais/revista/referencia/quadro-1.png +0 -0
- package/materiais/revista/referencia/quadro-2.png +0 -0
- package/materiais/revista/referencia/quadro-3.png +0 -0
- package/materiais/revista/referencia/quadro-4.png +0 -0
- package/materiais/revista/referencia/referencia.mp4 +0 -0
- package/materiais/revista/regras.md +130 -0
- package/materiais/revista/sons/Som.tsx +38 -0
- package/materiais/revista/texturas/Fundo.tsx +11 -0
- package/materiais/revista/texturas/Particulas.tsx +22 -0
- package/materiais/revista/tipografia/AssinaturaMarca.tsx +23 -0
- package/materiais/revista/tipografia/CitacaoGrande.tsx +27 -0
- package/materiais/revista/tipografia/TituloEditorial.tsx +31 -0
- package/materiais/revista/transicoes/Cena.tsx +41 -0
- package/materiais/revista/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/risografia/base.ts +73 -0
- package/materiais/risografia/camera/Camera.tsx +21 -0
- package/materiais/risografia/camera/CameraDeriva.tsx +37 -0
- package/materiais/risografia/cores/paleta.json +26 -0
- package/materiais/risografia/cores/paleta.png +0 -0
- package/materiais/risografia/formas/BolaReticula.tsx +26 -0
- package/materiais/risografia/formas/FormaRiso.tsx +24 -0
- package/materiais/risografia/formas/ListaRiso.tsx +22 -0
- package/materiais/risografia/formas/Overlay.tsx +18 -0
- package/materiais/risografia/formas/TarjaCarimbo.tsx +20 -0
- package/materiais/risografia/pecas.json +538 -0
- package/materiais/risografia/referencia/analise.md +82 -0
- package/materiais/risografia/referencia/quadro-1.png +0 -0
- package/materiais/risografia/referencia/quadro-2.png +0 -0
- package/materiais/risografia/referencia/quadro-3.png +0 -0
- package/materiais/risografia/referencia/quadro-4.png +0 -0
- package/materiais/risografia/referencia/referencia.mp4 +0 -0
- package/materiais/risografia/regras.md +123 -0
- package/materiais/risografia/sons/Som.tsx +30 -0
- package/materiais/risografia/texturas/Fundo.tsx +12 -0
- package/materiais/risografia/texturas/Particulas.tsx +22 -0
- package/materiais/risografia/tipografia/AssinaturaMarca.tsx +21 -0
- package/materiais/risografia/tipografia/NumeroRiso.tsx +21 -0
- package/materiais/risografia/tipografia/TituloRiso.tsx +26 -0
- package/materiais/risografia/transicoes/Cena.tsx +36 -0
- package/materiais/risografia/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/saas-linear/camera/CameraDeriva.tsx +37 -0
- package/materiais/saas-linear/cores/paleta.png +0 -0
- package/materiais/saas-linear/pecas.json +40 -34
- package/materiais/saas-linear/referencia/analise.md +87 -0
- package/materiais/saas-linear/referencia/quadro-1.png +0 -0
- package/materiais/saas-linear/referencia/quadro-2.png +0 -0
- package/materiais/saas-linear/referencia/quadro-3.png +0 -0
- package/materiais/saas-linear/referencia/quadro-4.png +0 -0
- package/materiais/saas-linear/referencia/referencia.mp4 +0 -0
- package/materiais/saas-linear/sons/Som.tsx +1 -1
- package/materiais/stripe-ondas/base.ts +85 -0
- package/materiais/stripe-ondas/camera/Camera.tsx +23 -0
- package/materiais/stripe-ondas/camera/CameraDeriva.tsx +37 -0
- package/materiais/stripe-ondas/cores/paleta.json +28 -0
- package/materiais/stripe-ondas/cores/paleta.png +0 -0
- package/materiais/stripe-ondas/formas/CartaoPagamento.tsx +35 -0
- package/materiais/stripe-ondas/formas/FaixaDeOndas.tsx +49 -0
- package/materiais/stripe-ondas/formas/GraficoOnda.tsx +34 -0
- package/materiais/stripe-ondas/formas/PainelCodigo.tsx +36 -0
- package/materiais/stripe-ondas/formas/SelosDeMetodo.tsx +27 -0
- package/materiais/stripe-ondas/pecas.json +510 -0
- package/materiais/stripe-ondas/referencia/analise.md +83 -0
- package/materiais/stripe-ondas/referencia/quadro-1.png +0 -0
- package/materiais/stripe-ondas/referencia/quadro-2.png +0 -0
- package/materiais/stripe-ondas/referencia/quadro-3.png +0 -0
- package/materiais/stripe-ondas/referencia/quadro-4.png +0 -0
- package/materiais/stripe-ondas/referencia/referencia.mp4 +0 -0
- package/materiais/stripe-ondas/regras.md +131 -0
- package/materiais/stripe-ondas/sons/Som.tsx +39 -0
- package/materiais/stripe-ondas/texturas/Fundo.tsx +11 -0
- package/materiais/stripe-ondas/texturas/Particulas.tsx +22 -0
- package/materiais/stripe-ondas/tipografia/AssinaturaMarca.tsx +18 -0
- package/materiais/stripe-ondas/tipografia/TituloLimpo.tsx +27 -0
- package/materiais/stripe-ondas/transicoes/Cena.tsx +46 -0
- package/materiais/stripe-ondas/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/suica/base.ts +76 -0
- package/materiais/suica/camera/CameraDeriva.tsx +37 -0
- package/materiais/suica/cores/paleta.json +27 -0
- package/materiais/suica/cores/paleta.png +0 -0
- package/materiais/suica/formas/DiscoFoto.tsx +20 -0
- package/materiais/suica/formas/Indice.tsx +17 -0
- package/materiais/suica/formas/ListaIndice.tsx +25 -0
- package/materiais/suica/formas/Regua.tsx +20 -0
- package/materiais/suica/pecas.json +528 -0
- package/materiais/suica/referencia/analise.md +80 -0
- package/materiais/suica/referencia/quadro-1.png +0 -0
- package/materiais/suica/referencia/quadro-2.png +0 -0
- package/materiais/suica/referencia/quadro-3.png +0 -0
- package/materiais/suica/referencia/quadro-4.png +0 -0
- package/materiais/suica/referencia/referencia.mp4 +0 -0
- package/materiais/suica/regras.md +129 -0
- package/materiais/suica/sons/Som.tsx +38 -0
- package/materiais/suica/texturas/Fundo.tsx +16 -0
- package/materiais/suica/texturas/GradeFotos.tsx +21 -0
- package/materiais/suica/texturas/Particulas.tsx +22 -0
- package/materiais/suica/tipografia/AssinaturaMarca.tsx +21 -0
- package/materiais/suica/tipografia/NumeroGigante.tsx +21 -0
- package/materiais/suica/tipografia/TituloGrade.tsx +38 -0
- package/materiais/suica/transicoes/Cena.tsx +41 -0
- package/materiais/suica/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/synthwave/base.ts +75 -0
- package/materiais/synthwave/camera/CameraDeriva.tsx +37 -0
- package/materiais/synthwave/cores/paleta.json +29 -0
- package/materiais/synthwave/cores/paleta.png +0 -0
- package/materiais/synthwave/formas/Montanhas.tsx +27 -0
- package/materiais/synthwave/formas/Palmeiras.tsx +30 -0
- package/materiais/synthwave/formas/QuadroHUD.tsx +33 -0
- package/materiais/synthwave/formas/SolListrado.tsx +29 -0
- package/materiais/synthwave/pecas.json +491 -0
- package/materiais/synthwave/referencia/analise.md +81 -0
- package/materiais/synthwave/referencia/quadro-1.png +0 -0
- package/materiais/synthwave/referencia/quadro-2.png +0 -0
- package/materiais/synthwave/referencia/quadro-3.png +0 -0
- package/materiais/synthwave/referencia/quadro-4.png +0 -0
- package/materiais/synthwave/referencia/referencia.mp4 +0 -0
- package/materiais/synthwave/regras.md +132 -0
- package/materiais/synthwave/sons/Som.tsx +38 -0
- package/materiais/synthwave/texturas/Estrelas.tsx +27 -0
- package/materiais/synthwave/texturas/Fundo.tsx +20 -0
- package/materiais/synthwave/texturas/Particulas.tsx +22 -0
- package/materiais/synthwave/tipografia/AssinaturaMarca.tsx +26 -0
- package/materiais/synthwave/tipografia/TituloNeon.tsx +30 -0
- package/materiais/synthwave/transicoes/Cena.tsx +41 -0
- package/materiais/synthwave/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/terminal/base.ts +67 -0
- package/materiais/terminal/camera/Camera.tsx +23 -0
- package/materiais/terminal/camera/CameraDeriva.tsx +37 -0
- package/materiais/terminal/cores/paleta.json +32 -0
- package/materiais/terminal/cores/paleta.png +0 -0
- package/materiais/terminal/formas/ArteAscii.tsx +61 -0
- package/materiais/terminal/formas/BarraProgresso.tsx +42 -0
- package/materiais/terminal/formas/BarraStatus.tsx +18 -0
- package/materiais/terminal/formas/BootBios.tsx +41 -0
- package/materiais/terminal/formas/LinhaComando.tsx +31 -0
- package/materiais/terminal/formas/Monitor.tsx +42 -0
- package/materiais/terminal/formas/PainelCaixa.tsx +35 -0
- package/materiais/terminal/formas/Tela.tsx +25 -0
- package/materiais/terminal/pecas.json +591 -0
- package/materiais/terminal/referencia/analise.md +84 -0
- package/materiais/terminal/referencia/quadro-1.png +0 -0
- package/materiais/terminal/referencia/quadro-2.png +0 -0
- package/materiais/terminal/referencia/quadro-3.png +0 -0
- package/materiais/terminal/referencia/quadro-4.png +0 -0
- package/materiais/terminal/referencia/referencia.mp4 +0 -0
- package/materiais/terminal/regras.md +124 -0
- package/materiais/terminal/sons/Som.tsx +32 -0
- package/materiais/terminal/texturas/Fundo.tsx +22 -0
- package/materiais/terminal/texturas/Particulas.tsx +22 -0
- package/materiais/terminal/tipografia/TextoGrande.tsx +35 -0
- package/materiais/terminal/transicoes/Cena.tsx +25 -0
- package/materiais/terminal/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/tiktok-energia/base.ts +92 -0
- package/materiais/tiktok-energia/camera/CameraDeriva.tsx +37 -0
- package/materiais/tiktok-energia/cores/paleta.json +27 -0
- package/materiais/tiktok-energia/cores/paleta.png +0 -0
- package/materiais/tiktok-energia/formas/EmojiSticker.tsx +21 -0
- package/materiais/tiktok-energia/formas/FotoSoco.tsx +27 -0
- package/materiais/tiktok-energia/pecas.json +470 -0
- package/materiais/tiktok-energia/referencia/analise.md +87 -0
- package/materiais/tiktok-energia/referencia/quadro-1.png +0 -0
- package/materiais/tiktok-energia/referencia/quadro-2.png +0 -0
- package/materiais/tiktok-energia/referencia/quadro-3.png +0 -0
- package/materiais/tiktok-energia/referencia/quadro-4.png +0 -0
- package/materiais/tiktok-energia/referencia/referencia.mp4 +0 -0
- package/materiais/tiktok-energia/regras.md +135 -0
- package/materiais/tiktok-energia/sons/Som.tsx +33 -0
- package/materiais/tiktok-energia/texturas/Fundo.tsx +8 -0
- package/materiais/tiktok-energia/texturas/Particulas.tsx +22 -0
- package/materiais/tiktok-energia/tipografia/AssinaturaMarca.tsx +25 -0
- package/materiais/tiktok-energia/tipografia/PalavraSoco.tsx +29 -0
- package/materiais/tiktok-energia/tipografia/TextoCaixa.tsx +25 -0
- package/materiais/tiktok-energia/transicoes/Cena.tsx +48 -0
- package/materiais/tiktok-energia/transicoes/CorteDeCor.tsx +22 -0
- package/materiais/tiktok-energia/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/tunel/base.ts +97 -0
- package/materiais/tunel/camera/CameraDeriva.tsx +37 -0
- package/materiais/tunel/cores/paleta.json +28 -0
- package/materiais/tunel/cores/paleta.png +0 -0
- package/materiais/tunel/formas/LinhasDeVelocidade.tsx +25 -0
- package/materiais/tunel/formas/PlacaVoadora.tsx +28 -0
- package/materiais/tunel/formas/TunelDeFormas.tsx +52 -0
- package/materiais/tunel/pecas.json +475 -0
- package/materiais/tunel/referencia/analise.md +83 -0
- package/materiais/tunel/referencia/quadro-1.png +0 -0
- package/materiais/tunel/referencia/quadro-2.png +0 -0
- package/materiais/tunel/referencia/quadro-3.png +0 -0
- package/materiais/tunel/referencia/quadro-4.png +0 -0
- package/materiais/tunel/referencia/referencia.mp4 +0 -0
- package/materiais/tunel/regras.md +134 -0
- package/materiais/tunel/sons/Som.tsx +33 -0
- package/materiais/tunel/texturas/Fundo.tsx +13 -0
- package/materiais/tunel/texturas/Particulas.tsx +22 -0
- package/materiais/tunel/tipografia/AssinaturaMarca.tsx +22 -0
- package/materiais/tunel/tipografia/NumeroGigante.tsx +28 -0
- package/materiais/tunel/tipografia/TituloTunel.tsx +32 -0
- package/materiais/tunel/transicoes/Cena.tsx +48 -0
- package/materiais/tunel/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/tutorial-tela/base.ts +65 -0
- package/materiais/tutorial-tela/camera/CameraDeriva.tsx +37 -0
- package/materiais/tutorial-tela/camera/CameraTela.tsx +29 -0
- package/materiais/tutorial-tela/cores/paleta.json +32 -0
- package/materiais/tutorial-tela/cores/paleta.png +0 -0
- package/materiais/tutorial-tela/formas/Cursor.tsx +36 -0
- package/materiais/tutorial-tela/formas/DestaqueCaixa.tsx +17 -0
- package/materiais/tutorial-tela/formas/JanelaApp.tsx +81 -0
- package/materiais/tutorial-tela/formas/TeclaAtalho.tsx +29 -0
- package/materiais/tutorial-tela/pecas.json +526 -0
- package/materiais/tutorial-tela/referencia/analise.md +86 -0
- package/materiais/tutorial-tela/referencia/quadro-1.png +0 -0
- package/materiais/tutorial-tela/referencia/quadro-2.png +0 -0
- package/materiais/tutorial-tela/referencia/quadro-3.png +0 -0
- package/materiais/tutorial-tela/referencia/quadro-4.png +0 -0
- package/materiais/tutorial-tela/referencia/referencia.mp4 +0 -0
- package/materiais/tutorial-tela/regras.md +139 -0
- package/materiais/tutorial-tela/sons/Som.tsx +41 -0
- package/materiais/tutorial-tela/texturas/Fundo.tsx +12 -0
- package/materiais/tutorial-tela/texturas/Particulas.tsx +22 -0
- package/materiais/tutorial-tela/tipografia/PassoChamada.tsx +22 -0
- package/materiais/tutorial-tela/tipografia/TituloTela.tsx +30 -0
- package/materiais/tutorial-tela/transicoes/Cena.tsx +33 -0
- package/materiais/tutorial-tela/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/ugc-reels/base.ts +92 -0
- package/materiais/ugc-reels/camera/CameraDeriva.tsx +37 -0
- package/materiais/ugc-reels/cores/paleta.json +28 -0
- package/materiais/ugc-reels/cores/paleta.png +0 -0
- package/materiais/ugc-reels/formas/BotaoLink.tsx +24 -0
- package/materiais/ugc-reels/formas/CabecalhoPerfil.tsx +38 -0
- package/materiais/ugc-reels/formas/Comentario.tsx +29 -0
- package/materiais/ugc-reels/formas/NotaDeMao.tsx +29 -0
- package/materiais/ugc-reels/formas/Reacoes.tsx +26 -0
- package/materiais/ugc-reels/formas/VideoCelular.tsx +37 -0
- package/materiais/ugc-reels/pecas.json +512 -0
- package/materiais/ugc-reels/referencia/analise.md +85 -0
- package/materiais/ugc-reels/referencia/quadro-1.png +0 -0
- package/materiais/ugc-reels/referencia/quadro-2.png +0 -0
- package/materiais/ugc-reels/referencia/quadro-3.png +0 -0
- package/materiais/ugc-reels/referencia/quadro-4.png +0 -0
- package/materiais/ugc-reels/referencia/referencia.mp4 +0 -0
- package/materiais/ugc-reels/regras.md +138 -0
- package/materiais/ugc-reels/sons/Som.tsx +33 -0
- package/materiais/ugc-reels/texturas/Fundo.tsx +8 -0
- package/materiais/ugc-reels/texturas/Particulas.tsx +22 -0
- package/materiais/ugc-reels/tipografia/AssinaturaMarca.tsx +28 -0
- package/materiais/ugc-reels/tipografia/LegendaEmoji.tsx +43 -0
- package/materiais/ugc-reels/transicoes/Cena.tsx +48 -0
- package/materiais/ugc-reels/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/vercel-mono/base.ts +82 -0
- package/materiais/vercel-mono/camera/Camera.tsx +23 -0
- package/materiais/vercel-mono/camera/CameraDeriva.tsx +37 -0
- package/materiais/vercel-mono/cores/paleta.json +25 -0
- package/materiais/vercel-mono/cores/paleta.png +0 -0
- package/materiais/vercel-mono/formas/FaixaOutline.tsx +25 -0
- package/materiais/vercel-mono/formas/Quadro.tsx +28 -0
- package/materiais/vercel-mono/formas/TerminalComando.tsx +33 -0
- package/materiais/vercel-mono/formas/TrianguloGigante.tsx +27 -0
- package/materiais/vercel-mono/pecas.json +504 -0
- package/materiais/vercel-mono/referencia/analise.md +82 -0
- package/materiais/vercel-mono/referencia/quadro-1.png +0 -0
- package/materiais/vercel-mono/referencia/quadro-2.png +0 -0
- package/materiais/vercel-mono/referencia/quadro-3.png +0 -0
- package/materiais/vercel-mono/referencia/quadro-4.png +0 -0
- package/materiais/vercel-mono/referencia/referencia.mp4 +0 -0
- package/materiais/vercel-mono/regras.md +120 -0
- package/materiais/vercel-mono/sons/Som.tsx +39 -0
- package/materiais/vercel-mono/texturas/Fundo.tsx +6 -0
- package/materiais/vercel-mono/texturas/GradeDeNumeros.tsx +27 -0
- package/materiais/vercel-mono/texturas/Particulas.tsx +22 -0
- package/materiais/vercel-mono/tipografia/AssinaturaMarca.tsx +18 -0
- package/materiais/vercel-mono/tipografia/PalavraMono.tsx +31 -0
- package/materiais/vercel-mono/transicoes/Cena.tsx +46 -0
- package/materiais/vercel-mono/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/vhs-90/base.ts +75 -0
- package/materiais/vhs-90/camera/CameraDeriva.tsx +37 -0
- package/materiais/vhs-90/cores/paleta.json +29 -0
- package/materiais/vhs-90/cores/paleta.png +0 -0
- package/materiais/vhs-90/formas/BarrasRastreio.tsx +21 -0
- package/materiais/vhs-90/formas/CapaVHS.tsx +28 -0
- package/materiais/vhs-90/formas/CarimboData.tsx +19 -0
- package/materiais/vhs-90/formas/MenuOSD.tsx +27 -0
- package/materiais/vhs-90/formas/TelaAzul.tsx +29 -0
- package/materiais/vhs-90/pecas.json +507 -0
- package/materiais/vhs-90/referencia/analise.md +81 -0
- package/materiais/vhs-90/referencia/quadro-1.png +0 -0
- package/materiais/vhs-90/referencia/quadro-2.png +0 -0
- package/materiais/vhs-90/referencia/quadro-3.png +0 -0
- package/materiais/vhs-90/referencia/quadro-4.png +0 -0
- package/materiais/vhs-90/referencia/referencia.mp4 +0 -0
- package/materiais/vhs-90/regras.md +133 -0
- package/materiais/vhs-90/sons/Som.tsx +38 -0
- package/materiais/vhs-90/texturas/Fundo.tsx +27 -0
- package/materiais/vhs-90/texturas/Particulas.tsx +22 -0
- package/materiais/vhs-90/tipografia/AssinaturaMarca.tsx +29 -0
- package/materiais/vhs-90/tipografia/TituloFita.tsx +40 -0
- package/materiais/vhs-90/transicoes/Cena.tsx +41 -0
- package/materiais/vhs-90/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/vidro-ios/base.ts +87 -0
- package/materiais/vidro-ios/camera/Camera.tsx +23 -0
- package/materiais/vidro-ios/camera/CameraDeriva.tsx +37 -0
- package/materiais/vidro-ios/cores/paleta.json +28 -0
- package/materiais/vidro-ios/cores/paleta.png +0 -0
- package/materiais/vidro-ios/formas/IlhaDinamica.tsx +24 -0
- package/materiais/vidro-ios/formas/PainelControle.tsx +33 -0
- package/materiais/vidro-ios/formas/PilhaNotificacoes.tsx +29 -0
- package/materiais/vidro-ios/formas/WidgetsGrade.tsx +34 -0
- package/materiais/vidro-ios/formas/vidro.tsx +20 -0
- package/materiais/vidro-ios/pecas.json +504 -0
- package/materiais/vidro-ios/referencia/analise.md +84 -0
- package/materiais/vidro-ios/referencia/quadro-1.png +0 -0
- package/materiais/vidro-ios/referencia/quadro-2.png +0 -0
- package/materiais/vidro-ios/referencia/quadro-3.png +0 -0
- package/materiais/vidro-ios/referencia/quadro-4.png +0 -0
- package/materiais/vidro-ios/referencia/referencia.mp4 +0 -0
- package/materiais/vidro-ios/regras.md +127 -0
- package/materiais/vidro-ios/sons/Som.tsx +39 -0
- package/materiais/vidro-ios/texturas/Fundo.tsx +17 -0
- package/materiais/vidro-ios/texturas/Particulas.tsx +22 -0
- package/materiais/vidro-ios/tipografia/AssinaturaMarca.tsx +21 -0
- package/materiais/vidro-ios/tipografia/TituloVidro.tsx +22 -0
- package/materiais/vidro-ios/transicoes/Cena.tsx +46 -0
- package/materiais/vidro-ios/transicoes/CorteImpacto.tsx +16 -0
- package/materiais/y2k-cromado/base.ts +75 -0
- package/materiais/y2k-cromado/camera/CameraDeriva.tsx +37 -0
- package/materiais/y2k-cromado/cores/paleta.json +29 -0
- package/materiais/y2k-cromado/cores/paleta.png +0 -0
- package/materiais/y2k-cromado/formas/Bolhas.tsx +30 -0
- package/materiais/y2k-cromado/formas/CartaoGloss.tsx +26 -0
- package/materiais/y2k-cromado/formas/FitaMarquee.tsx +20 -0
- package/materiais/y2k-cromado/formas/JanelaY2K.tsx +31 -0
- package/materiais/y2k-cromado/formas/OrbeCromo.tsx +20 -0
- package/materiais/y2k-cromado/pecas.json +527 -0
- package/materiais/y2k-cromado/referencia/analise.md +81 -0
- package/materiais/y2k-cromado/referencia/quadro-1.png +0 -0
- package/materiais/y2k-cromado/referencia/quadro-2.png +0 -0
- package/materiais/y2k-cromado/referencia/quadro-3.png +0 -0
- package/materiais/y2k-cromado/referencia/quadro-4.png +0 -0
- package/materiais/y2k-cromado/referencia/referencia.mp4 +0 -0
- package/materiais/y2k-cromado/regras.md +133 -0
- package/materiais/y2k-cromado/sons/Som.tsx +38 -0
- package/materiais/y2k-cromado/texturas/Brilhos.tsx +28 -0
- package/materiais/y2k-cromado/texturas/Fundo.tsx +18 -0
- package/materiais/y2k-cromado/texturas/Particulas.tsx +22 -0
- package/materiais/y2k-cromado/tipografia/AssinaturaMarca.tsx +25 -0
- package/materiais/y2k-cromado/tipografia/TextoCromo.tsx +34 -0
- package/materiais/y2k-cromado/transicoes/Cena.tsx +41 -0
- package/materiais/y2k-cromado/transicoes/CorteImpacto.tsx +16 -0
- package/package.json +1 -1
- package/skills/apresentacao-pptx/SKILL.md +1 -1
- package/skills/carrossel-conferido/SKILL.md +21 -0
- package/skills/cartaz-conferido/SKILL.md +28 -0
- package/skills/deck-conferido/SKILL.md +5 -4
- package/skills/documento-conferido/SKILL.md +23 -0
- package/vendor/fontes/anton.woff2 +0 -0
- package/vendor/fontes/caveat.woff2 +0 -0
- package/vendor/fontes/inter.woff2 +0 -0
- package/vendor/fontes/jetbrains-mono.woff2 +0 -0
- package/vendor/fontes/montserrat.woff2 +0 -0
- package/voz/primo_voz/__main__.py +1 -1
- package/voz/primo_voz/app.py +8 -8
- package/voz/primo_voz/transcrever.py +2 -2
- package/kits/adesivos/assets/ASSETS.md +0 -22
- package/kits/adesivos/elementos/AdesivoForma.tsx +0 -42
- package/kits/adesivos/elementos/AdesivoFoto.tsx +0 -36
- package/kits/adesivos/elementos/AdesivoTexto.tsx +0 -35
- package/kits/adesivos/elementos/AssinaturaMarca.tsx +0 -36
- package/kits/adesivos/elementos/Cena.tsx +0 -48
- package/kits/adesivos/elementos/ChuvaDeAdesivos.tsx +0 -29
- package/kits/adesivos/elementos/Fundo.tsx +0 -21
- package/kits/adesivos/elementos/Montagem.tsx +0 -68
- package/kits/adesivos/elementos/SeloPreco.tsx +0 -38
- package/kits/adesivos/elementos/Som.tsx +0 -33
- package/kits/adesivos/elementos/TituloEtiquetas.tsx +0 -33
- package/kits/adesivos/elementos/base.ts +0 -101
- package/kits/adesivos/elementos/index.ts +0 -16
- package/kits/adesivos/exemplos/fotos/foto-01.jpg +0 -0
- package/kits/adesivos/exemplos/fotos/foto-02.jpg +0 -0
- package/kits/adesivos/exemplos/fotos/foto-03.jpg +0 -0
- package/kits/adesivos/exemplos/logo-grude.svg +0 -1
- package/kits/adesivos/exemplos/plano.json +0 -328
- package/kits/adesivos/exemplos/roteiro.md +0 -21
- package/kits/adesivos/preview.tsx +0 -15
- package/kits/adesivos/receita.json +0 -212
- package/kits/adesivos/regras/area-segura.md +0 -17
- package/kits/adesivos/regras/cor.md +0 -23
- package/kits/adesivos/regras/movimento.md +0 -17
- package/kits/adesivos/regras/ritmo.md +0 -16
- package/kits/adesivos/regras/som.md +0 -20
- package/kits/adesivos/regras/tipografia.md +0 -16
- package/kits/antes-depois/assets/ASSETS.md +0 -23
- package/kits/antes-depois/elementos/BarraMedidor.tsx +0 -43
- package/kits/antes-depois/elementos/Cena.tsx +0 -41
- package/kits/antes-depois/elementos/FaixaMarquee.tsx +0 -35
- package/kits/antes-depois/elementos/Fundo.tsx +0 -24
- package/kits/antes-depois/elementos/ListaMudancas.tsx +0 -37
- package/kits/antes-depois/elementos/Montagem.tsx +0 -59
- package/kits/antes-depois/elementos/NumeroDelta.tsx +0 -36
- package/kits/antes-depois/elementos/RotuloAntesDepois.tsx +0 -26
- package/kits/antes-depois/elementos/Som.tsx +0 -40
- package/kits/antes-depois/elementos/TelaDividida.tsx +0 -68
- package/kits/antes-depois/elementos/base.ts +0 -82
- package/kits/antes-depois/elementos/index.ts +0 -15
- package/kits/antes-depois/exemplos/fotos/foto-07.jpg +0 -0
- package/kits/antes-depois/exemplos/fotos/foto-08.jpg +0 -0
- package/kits/antes-depois/exemplos/plano.json +0 -276
- package/kits/antes-depois/exemplos/roteiro.md +0 -19
- package/kits/antes-depois/preview.tsx +0 -13
- package/kits/antes-depois/receita.json +0 -21
- package/kits/antes-depois/regras/area-segura.md +0 -21
- package/kits/antes-depois/regras/cor.md +0 -15
- package/kits/antes-depois/regras/movimento.md +0 -23
- package/kits/antes-depois/regras/ritmo.md +0 -15
- package/kits/antes-depois/regras/som.md +0 -20
- package/kits/antes-depois/regras/tipografia.md +0 -18
- package/kits/apple-tipografico/assets/ASSETS.md +0 -23
- package/kits/apple-tipografico/elementos/AssinaturaPreta.tsx +0 -33
- package/kits/apple-tipografico/elementos/Camera.tsx +0 -23
- package/kits/apple-tipografico/elementos/CartaoRadial.tsx +0 -41
- package/kits/apple-tipografico/elementos/Cena.tsx +0 -55
- package/kits/apple-tipografico/elementos/Fundo.tsx +0 -21
- package/kits/apple-tipografico/elementos/LegendaCurta.tsx +0 -51
- package/kits/apple-tipografico/elementos/Montagem.tsx +0 -55
- package/kits/apple-tipografico/elementos/Produto3D.tsx +0 -140
- package/kits/apple-tipografico/elementos/ProdutoFoto.tsx +0 -47
- package/kits/apple-tipografico/elementos/Som.tsx +0 -40
- package/kits/apple-tipografico/elementos/base.ts +0 -111
- package/kits/apple-tipografico/elementos/index.ts +0 -18
- package/kits/apple-tipografico/exemplos/logo-lume.svg +0 -1
- package/kits/apple-tipografico/exemplos/plano.json +0 -56
- package/kits/apple-tipografico/exemplos/roteiro.md +0 -19
- package/kits/apple-tipografico/preview.tsx +0 -12
- package/kits/apple-tipografico/receita.json +0 -22
- package/kits/apple-tipografico/regras/area-segura.md +0 -19
- package/kits/apple-tipografico/regras/cor.md +0 -24
- package/kits/apple-tipografico/regras/movimento.md +0 -29
- package/kits/apple-tipografico/regras/ritmo.md +0 -29
- package/kits/apple-tipografico/regras/som.md +0 -20
- package/kits/apple-tipografico/regras/tipografia.md +0 -21
- package/kits/aquarela/assets/ASSETS.md +0 -21
- package/kits/aquarela/elementos/AnotacaoManual.tsx +0 -40
- package/kits/aquarela/elementos/AssinaturaMarca.tsx +0 -33
- package/kits/aquarela/elementos/Cena.tsx +0 -48
- package/kits/aquarela/elementos/Fundo.tsx +0 -24
- package/kits/aquarela/elementos/ManchaTinta.tsx +0 -46
- package/kits/aquarela/elementos/Montagem.tsx +0 -60
- package/kits/aquarela/elementos/PapelRasgado.tsx +0 -50
- package/kits/aquarela/elementos/Pincelada.tsx +0 -43
- package/kits/aquarela/elementos/Pingos.tsx +0 -31
- package/kits/aquarela/elementos/Som.tsx +0 -33
- package/kits/aquarela/elementos/TituloPincel.tsx +0 -51
- package/kits/aquarela/elementos/base.ts +0 -97
- package/kits/aquarela/elementos/index.ts +0 -16
- package/kits/aquarela/exemplos/logo-mare.svg +0 -1
- package/kits/aquarela/exemplos/plano.json +0 -62
- package/kits/aquarela/exemplos/roteiro.md +0 -21
- package/kits/aquarela/preview.tsx +0 -12
- package/kits/aquarela/receita.json +0 -213
- package/kits/aquarela/regras/area-segura.md +0 -17
- package/kits/aquarela/regras/cor.md +0 -23
- package/kits/aquarela/regras/movimento.md +0 -19
- package/kits/aquarela/regras/ritmo.md +0 -17
- package/kits/aquarela/regras/som.md +0 -20
- package/kits/aquarela/regras/tipografia.md +0 -16
- package/kits/aurora/assets/ASSETS.md +0 -21
- package/kits/aurora/elementos/AssinaturaMarca.tsx +0 -24
- package/kits/aurora/elementos/CartaoVidro.tsx +0 -29
- package/kits/aurora/elementos/Cena.tsx +0 -48
- package/kits/aurora/elementos/CeuEstrelado.tsx +0 -22
- package/kits/aurora/elementos/CortinaDeLuz.tsx +0 -36
- package/kits/aurora/elementos/Fundo.tsx +0 -35
- package/kits/aurora/elementos/Legenda.tsx +0 -23
- package/kits/aurora/elementos/Montagem.tsx +0 -68
- package/kits/aurora/elementos/Montanhas.tsx +0 -24
- package/kits/aurora/elementos/Som.tsx +0 -33
- package/kits/aurora/elementos/TituloSerif.tsx +0 -36
- package/kits/aurora/elementos/base.ts +0 -93
- package/kits/aurora/elementos/index.ts +0 -16
- package/kits/aurora/exemplos/logo-boreal.svg +0 -1
- package/kits/aurora/exemplos/plano.json +0 -204
- package/kits/aurora/exemplos/roteiro.md +0 -19
- package/kits/aurora/preview.tsx +0 -12
- package/kits/aurora/receita.json +0 -146
- package/kits/aurora/regras/area-segura.md +0 -18
- package/kits/aurora/regras/cor.md +0 -24
- package/kits/aurora/regras/movimento.md +0 -20
- package/kits/aurora/regras/ritmo.md +0 -14
- package/kits/aurora/regras/som.md +0 -20
- package/kits/aurora/regras/tipografia.md +0 -15
- package/kits/bauhaus/assets/ASSETS.md +0 -18
- package/kits/bauhaus/elementos/AssinaturaMarca.tsx +0 -26
- package/kits/bauhaus/elementos/BarraDiagonal.tsx +0 -20
- package/kits/bauhaus/elementos/Camera.tsx +0 -21
- package/kits/bauhaus/elementos/Cena.tsx +0 -36
- package/kits/bauhaus/elementos/ComposicaoGeometrica.tsx +0 -54
- package/kits/bauhaus/elementos/Fundo.tsx +0 -13
- package/kits/bauhaus/elementos/ListaFaixas.tsx +0 -27
- package/kits/bauhaus/elementos/Montagem.tsx +0 -55
- package/kits/bauhaus/elementos/NumeroBauhaus.tsx +0 -21
- package/kits/bauhaus/elementos/Overlay.tsx +0 -18
- package/kits/bauhaus/elementos/Som.tsx +0 -30
- package/kits/bauhaus/elementos/TituloBauhaus.tsx +0 -32
- package/kits/bauhaus/elementos/base.ts +0 -74
- package/kits/bauhaus/elementos/index.ts +0 -16
- package/kits/bauhaus/exemplos/plano.json +0 -221
- package/kits/bauhaus/exemplos/roteiro.md +0 -20
- package/kits/bauhaus/preview.tsx +0 -12
- package/kits/bauhaus/receita.json +0 -174
- package/kits/bauhaus/regras/area-segura.md +0 -15
- package/kits/bauhaus/regras/cor.md +0 -13
- package/kits/bauhaus/regras/movimento.md +0 -17
- package/kits/bauhaus/regras/ritmo.md +0 -15
- package/kits/bauhaus/regras/som.md +0 -18
- package/kits/bauhaus/regras/tipografia.md +0 -20
- package/kits/brutalista/assets/ASSETS.md +0 -23
- package/kits/brutalista/elementos/AssinaturaMarca.tsx +0 -21
- package/kits/brutalista/elementos/BlocoSombra.tsx +0 -18
- package/kits/brutalista/elementos/CartaoFotoBruto.tsx +0 -19
- package/kits/brutalista/elementos/Cena.tsx +0 -41
- package/kits/brutalista/elementos/ContadorGrande.tsx +0 -21
- package/kits/brutalista/elementos/FitaAlerta.tsx +0 -20
- package/kits/brutalista/elementos/Fundo.tsx +0 -9
- package/kits/brutalista/elementos/ListaBruta.tsx +0 -23
- package/kits/brutalista/elementos/MonoEnorme.tsx +0 -43
- package/kits/brutalista/elementos/Montagem.tsx +0 -62
- package/kits/brutalista/elementos/QuadroCor.tsx +0 -14
- package/kits/brutalista/elementos/Som.tsx +0 -38
- package/kits/brutalista/elementos/Terminal.tsx +0 -25
- package/kits/brutalista/elementos/base.ts +0 -71
- package/kits/brutalista/elementos/index.ts +0 -18
- package/kits/brutalista/exemplos/fotos/foto-02.jpg +0 -0
- package/kits/brutalista/exemplos/fotos/foto-03.jpg +0 -0
- package/kits/brutalista/exemplos/fotos/foto-05.jpg +0 -0
- package/kits/brutalista/exemplos/fotos/foto-07.jpg +0 -0
- package/kits/brutalista/exemplos/fotos/foto-08.jpg +0 -0
- package/kits/brutalista/exemplos/logo-bloco.svg +0 -1
- package/kits/brutalista/exemplos/plano.json +0 -52
- package/kits/brutalista/exemplos/roteiro.md +0 -19
- package/kits/brutalista/preview.tsx +0 -20
- package/kits/brutalista/receita.json +0 -195
- package/kits/brutalista/regras/area-segura.md +0 -18
- package/kits/brutalista/regras/cor.md +0 -12
- package/kits/brutalista/regras/movimento.md +0 -16
- package/kits/brutalista/regras/ritmo.md +0 -16
- package/kits/brutalista/regras/som.md +0 -21
- package/kits/brutalista/regras/tipografia.md +0 -16
- package/kits/campos-de-cor/assets/ASSETS.md +0 -19
- package/kits/campos-de-cor/elementos/AssinaturaMarca.tsx +0 -18
- package/kits/campos-de-cor/elementos/Asterisco.tsx +0 -26
- package/kits/campos-de-cor/elementos/Camera.tsx +0 -23
- package/kits/campos-de-cor/elementos/CampoDeCor.tsx +0 -39
- package/kits/campos-de-cor/elementos/Cena.tsx +0 -46
- package/kits/campos-de-cor/elementos/FitaDeTexto.tsx +0 -24
- package/kits/campos-de-cor/elementos/FormaGeometrica.tsx +0 -37
- package/kits/campos-de-cor/elementos/Fundo.tsx +0 -11
- package/kits/campos-de-cor/elementos/LegendaItalica.tsx +0 -12
- package/kits/campos-de-cor/elementos/ListaRegua.tsx +0 -30
- package/kits/campos-de-cor/elementos/Montagem.tsx +0 -62
- package/kits/campos-de-cor/elementos/PalavraGigante.tsx +0 -44
- package/kits/campos-de-cor/elementos/Som.tsx +0 -39
- package/kits/campos-de-cor/elementos/base.ts +0 -87
- package/kits/campos-de-cor/elementos/index.ts +0 -17
- package/kits/campos-de-cor/exemplos/logo-pulso.svg +0 -1
- package/kits/campos-de-cor/exemplos/plano.json +0 -258
- package/kits/campos-de-cor/exemplos/roteiro.md +0 -19
- package/kits/campos-de-cor/preview.tsx +0 -12
- package/kits/campos-de-cor/receita.json +0 -174
- package/kits/campos-de-cor/regras/area-segura.md +0 -15
- package/kits/campos-de-cor/regras/cor.md +0 -14
- package/kits/campos-de-cor/regras/movimento.md +0 -15
- package/kits/campos-de-cor/regras/ritmo.md +0 -15
- package/kits/campos-de-cor/regras/som.md +0 -18
- package/kits/campos-de-cor/regras/tipografia.md +0 -13
- package/kits/cartaz-cinetico/assets/ASSETS.md +0 -22
- package/kits/cartaz-cinetico/elementos/AssinaturaMarca.tsx +0 -31
- package/kits/cartaz-cinetico/elementos/CartazPalavra.tsx +0 -40
- package/kits/cartaz-cinetico/elementos/Cena.tsx +0 -41
- package/kits/cartaz-cinetico/elementos/CirculoPoster.tsx +0 -22
- package/kits/cartaz-cinetico/elementos/EcoPalavra.tsx +0 -27
- package/kits/cartaz-cinetico/elementos/Fundo.tsx +0 -16
- package/kits/cartaz-cinetico/elementos/Montagem.tsx +0 -59
- package/kits/cartaz-cinetico/elementos/PilhaCartaz.tsx +0 -40
- package/kits/cartaz-cinetico/elementos/RoletaPalavras.tsx +0 -30
- package/kits/cartaz-cinetico/elementos/Selo.tsx +0 -25
- package/kits/cartaz-cinetico/elementos/Som.tsx +0 -38
- package/kits/cartaz-cinetico/elementos/base.ts +0 -72
- package/kits/cartaz-cinetico/elementos/index.ts +0 -16
- package/kits/cartaz-cinetico/exemplos/logo-feira.svg +0 -1
- package/kits/cartaz-cinetico/exemplos/plano.json +0 -55
- package/kits/cartaz-cinetico/exemplos/roteiro.md +0 -20
- package/kits/cartaz-cinetico/preview.tsx +0 -16
- package/kits/cartaz-cinetico/receita.json +0 -209
- package/kits/cartaz-cinetico/regras/area-segura.md +0 -19
- package/kits/cartaz-cinetico/regras/cor.md +0 -13
- package/kits/cartaz-cinetico/regras/movimento.md +0 -16
- package/kits/cartaz-cinetico/regras/ritmo.md +0 -17
- package/kits/cartaz-cinetico/regras/som.md +0 -21
- package/kits/cartaz-cinetico/regras/tipografia.md +0 -16
- package/kits/colagem/assets/ASSETS.md +0 -25
- package/kits/colagem/elementos/AssinaturaMarca.tsx +0 -17
- package/kits/colagem/elementos/Camera.tsx +0 -21
- package/kits/colagem/elementos/Cena.tsx +0 -36
- package/kits/colagem/elementos/FitaAdesiva.tsx +0 -11
- package/kits/colagem/elementos/FotoRasgada.tsx +0 -26
- package/kits/colagem/elementos/Fundo.tsx +0 -16
- package/kits/colagem/elementos/ListaRecortes.tsx +0 -23
- package/kits/colagem/elementos/Montagem.tsx +0 -56
- package/kits/colagem/elementos/NotaDatilografada.tsx +0 -35
- package/kits/colagem/elementos/RecorteForma.tsx +0 -23
- package/kits/colagem/elementos/Som.tsx +0 -30
- package/kits/colagem/elementos/TituloRecorte.tsx +0 -34
- package/kits/colagem/elementos/base.ts +0 -77
- package/kits/colagem/elementos/index.ts +0 -17
- package/kits/colagem/elementos/rasgado.ts +0 -16
- package/kits/colagem/exemplos/fotos/foto-01.jpg +0 -0
- package/kits/colagem/exemplos/fotos/foto-02.jpg +0 -0
- package/kits/colagem/exemplos/plano.json +0 -228
- package/kits/colagem/exemplos/roteiro.md +0 -20
- package/kits/colagem/preview.tsx +0 -13
- package/kits/colagem/receita.json +0 -171
- package/kits/colagem/regras/area-segura.md +0 -15
- package/kits/colagem/regras/cor.md +0 -16
- package/kits/colagem/regras/movimento.md +0 -18
- package/kits/colagem/regras/ritmo.md +0 -15
- package/kits/colagem/regras/som.md +0 -18
- package/kits/colagem/regras/tipografia.md +0 -18
- package/kits/contagem/assets/ASSETS.md +0 -20
- package/kits/contagem/elementos/AnelTempo.tsx +0 -36
- package/kits/contagem/elementos/BarraDias.tsx +0 -41
- package/kits/contagem/elementos/CarimboData.tsx +0 -37
- package/kits/contagem/elementos/Cena.tsx +0 -39
- package/kits/contagem/elementos/Fundo.tsx +0 -27
- package/kits/contagem/elementos/Montagem.tsx +0 -58
- package/kits/contagem/elementos/NumeroRolando.tsx +0 -49
- package/kits/contagem/elementos/RelogioFlip.tsx +0 -51
- package/kits/contagem/elementos/Som.tsx +0 -41
- package/kits/contagem/elementos/base.ts +0 -79
- package/kits/contagem/elementos/index.ts +0 -14
- package/kits/contagem/exemplos/plano.json +0 -48
- package/kits/contagem/exemplos/roteiro.md +0 -19
- package/kits/contagem/preview.tsx +0 -9
- package/kits/contagem/receita.json +0 -21
- package/kits/contagem/regras/area-segura.md +0 -16
- package/kits/contagem/regras/cor.md +0 -14
- package/kits/contagem/regras/movimento.md +0 -23
- package/kits/contagem/regras/ritmo.md +0 -15
- package/kits/contagem/regras/som.md +0 -21
- package/kits/contagem/regras/tipografia.md +0 -16
- package/kits/convite-evento/assets/ASSETS.md +0 -19
- package/kits/convite-evento/elementos/BotaoInscricao.tsx +0 -36
- package/kits/convite-evento/elementos/Cena.tsx +0 -39
- package/kits/convite-evento/elementos/DataGigante.tsx +0 -37
- package/kits/convite-evento/elementos/Fundo.tsx +0 -30
- package/kits/convite-evento/elementos/IngressoBilhete.tsx +0 -40
- package/kits/convite-evento/elementos/LugarGigante.tsx +0 -38
- package/kits/convite-evento/elementos/Montagem.tsx +0 -59
- package/kits/convite-evento/elementos/SeloRotativo.tsx +0 -32
- package/kits/convite-evento/elementos/Som.tsx +0 -40
- package/kits/convite-evento/elementos/TituloEvento.tsx +0 -33
- package/kits/convite-evento/elementos/base.ts +0 -82
- package/kits/convite-evento/elementos/index.ts +0 -15
- package/kits/convite-evento/exemplos/plano.json +0 -49
- package/kits/convite-evento/exemplos/roteiro.md +0 -19
- package/kits/convite-evento/preview.tsx +0 -9
- package/kits/convite-evento/receita.json +0 -21
- package/kits/convite-evento/regras/area-segura.md +0 -20
- package/kits/convite-evento/regras/cor.md +0 -13
- package/kits/convite-evento/regras/movimento.md +0 -20
- package/kits/convite-evento/regras/ritmo.md +0 -15
- package/kits/convite-evento/regras/som.md +0 -20
- package/kits/convite-evento/regras/tipografia.md +0 -18
- package/kits/corte-podcast/assets/ASSETS.md +0 -19
- package/kits/corte-podcast/elementos/BarraEpisodio.tsx +0 -43
- package/kits/corte-podcast/elementos/CartaoConvidado.tsx +0 -32
- package/kits/corte-podcast/elementos/Cena.tsx +0 -41
- package/kits/corte-podcast/elementos/CitacaoGrande.tsx +0 -42
- package/kits/corte-podcast/elementos/Fundo.tsx +0 -27
- package/kits/corte-podcast/elementos/LegendaKaraoke.tsx +0 -32
- package/kits/corte-podcast/elementos/Montagem.tsx +0 -59
- package/kits/corte-podcast/elementos/OndaAudio.tsx +0 -41
- package/kits/corte-podcast/elementos/SeloEpisodio.tsx +0 -33
- package/kits/corte-podcast/elementos/Som.tsx +0 -40
- package/kits/corte-podcast/elementos/base.ts +0 -82
- package/kits/corte-podcast/elementos/index.ts +0 -15
- package/kits/corte-podcast/exemplos/plano.json +0 -62
- package/kits/corte-podcast/exemplos/roteiro.md +0 -20
- package/kits/corte-podcast/preview.tsx +0 -9
- package/kits/corte-podcast/receita.json +0 -21
- package/kits/corte-podcast/regras/area-segura.md +0 -18
- package/kits/corte-podcast/regras/cor.md +0 -15
- package/kits/corte-podcast/regras/movimento.md +0 -18
- package/kits/corte-podcast/regras/ritmo.md +0 -16
- package/kits/corte-podcast/regras/som.md +0 -20
- package/kits/corte-podcast/regras/tipografia.md +0 -16
- package/kits/cubos/assets/ASSETS.md +0 -21
- package/kits/cubos/elementos/AssinaturaMarca.tsx +0 -29
- package/kits/cubos/elementos/Cena.tsx +0 -48
- package/kits/cubos/elementos/Cubo.tsx +0 -40
- package/kits/cubos/elementos/CuboGiratorio.tsx +0 -37
- package/kits/cubos/elementos/Fundo.tsx +0 -15
- package/kits/cubos/elementos/Montagem.tsx +0 -67
- package/kits/cubos/elementos/MontagemDeCubos.tsx +0 -58
- package/kits/cubos/elementos/PlacaBloco.tsx +0 -29
- package/kits/cubos/elementos/Som.tsx +0 -33
- package/kits/cubos/elementos/TorreDeCubos.tsx +0 -39
- package/kits/cubos/elementos/base.ts +0 -97
- package/kits/cubos/elementos/index.ts +0 -15
- package/kits/cubos/exemplos/logo-encaixa.svg +0 -1
- package/kits/cubos/exemplos/plano.json +0 -45
- package/kits/cubos/exemplos/roteiro.md +0 -20
- package/kits/cubos/preview.tsx +0 -12
- package/kits/cubos/receita.json +0 -151
- package/kits/cubos/regras/area-segura.md +0 -18
- package/kits/cubos/regras/cor.md +0 -23
- package/kits/cubos/regras/movimento.md +0 -17
- package/kits/cubos/regras/ritmo.md +0 -14
- package/kits/cubos/regras/som.md +0 -20
- package/kits/cubos/regras/tipografia.md +0 -15
- package/kits/dashboard-dados/assets/ASSETS.md +0 -18
- package/kits/dashboard-dados/elementos/AssinaturaMarca.tsx +0 -19
- package/kits/dashboard-dados/elementos/BarrasCrescendo.tsx +0 -27
- package/kits/dashboard-dados/elementos/Camera.tsx +0 -23
- package/kits/dashboard-dados/elementos/Cena.tsx +0 -46
- package/kits/dashboard-dados/elementos/Fundo.tsx +0 -12
- package/kits/dashboard-dados/elementos/LinhaTendencia.tsx +0 -29
- package/kits/dashboard-dados/elementos/Montagem.tsx +0 -60
- package/kits/dashboard-dados/elementos/NumeroGigante.tsx +0 -21
- package/kits/dashboard-dados/elementos/RankingBarras.tsx +0 -27
- package/kits/dashboard-dados/elementos/RoscaDados.tsx +0 -39
- package/kits/dashboard-dados/elementos/Som.tsx +0 -39
- package/kits/dashboard-dados/elementos/base.ts +0 -87
- package/kits/dashboard-dados/elementos/index.ts +0 -16
- package/kits/dashboard-dados/exemplos/logo-radar.svg +0 -1
- package/kits/dashboard-dados/exemplos/plano.json +0 -325
- package/kits/dashboard-dados/exemplos/roteiro.md +0 -20
- package/kits/dashboard-dados/preview.tsx +0 -12
- package/kits/dashboard-dados/receita.json +0 -173
- package/kits/dashboard-dados/regras/area-segura.md +0 -13
- package/kits/dashboard-dados/regras/cor.md +0 -17
- package/kits/dashboard-dados/regras/movimento.md +0 -17
- package/kits/dashboard-dados/regras/ritmo.md +0 -14
- package/kits/dashboard-dados/regras/som.md +0 -18
- package/kits/dashboard-dados/regras/tipografia.md +0 -16
- package/kits/depoimento/assets/ASSETS.md +0 -20
- package/kits/depoimento/elementos/Avatar.tsx +0 -37
- package/kits/depoimento/elementos/CartaoDepoimento.tsx +0 -69
- package/kits/depoimento/elementos/Cena.tsx +0 -39
- package/kits/depoimento/elementos/Estrelas.tsx +0 -34
- package/kits/depoimento/elementos/FaixaAvatares.tsx +0 -41
- package/kits/depoimento/elementos/Fundo.tsx +0 -23
- package/kits/depoimento/elementos/Montagem.tsx +0 -60
- package/kits/depoimento/elementos/NotaGigante.tsx +0 -38
- package/kits/depoimento/elementos/PilhaCartoes.tsx +0 -37
- package/kits/depoimento/elementos/SeloVerificado.tsx +0 -29
- package/kits/depoimento/elementos/Som.tsx +0 -41
- package/kits/depoimento/elementos/base.ts +0 -83
- package/kits/depoimento/elementos/index.ts +0 -16
- package/kits/depoimento/exemplos/plano.json +0 -57
- package/kits/depoimento/exemplos/roteiro.md +0 -19
- package/kits/depoimento/preview.tsx +0 -9
- package/kits/depoimento/receita.json +0 -21
- package/kits/depoimento/regras/area-segura.md +0 -17
- package/kits/depoimento/regras/cor.md +0 -16
- package/kits/depoimento/regras/movimento.md +0 -20
- package/kits/depoimento/regras/ritmo.md +0 -15
- package/kits/depoimento/regras/som.md +0 -21
- package/kits/depoimento/regras/tipografia.md +0 -17
- package/kits/infografico/assets/ASSETS.md +0 -19
- package/kits/infografico/elementos/Anotacao.tsx +0 -34
- package/kits/infografico/elementos/CadeiaPassos.tsx +0 -49
- package/kits/infografico/elementos/Cena.tsx +0 -39
- package/kits/infografico/elementos/Fundo.tsx +0 -23
- package/kits/infografico/elementos/GraficoBarras.tsx +0 -41
- package/kits/infografico/elementos/Icone.tsx +0 -35
- package/kits/infografico/elementos/Montagem.tsx +0 -60
- package/kits/infografico/elementos/NoProcesso.tsx +0 -33
- package/kits/infografico/elementos/NumeroDestaque.tsx +0 -35
- package/kits/infografico/elementos/SetaCurva.tsx +0 -33
- package/kits/infografico/elementos/Som.tsx +0 -40
- package/kits/infografico/elementos/base.ts +0 -80
- package/kits/infografico/elementos/index.ts +0 -16
- package/kits/infografico/exemplos/plano.json +0 -49
- package/kits/infografico/exemplos/roteiro.md +0 -19
- package/kits/infografico/preview.tsx +0 -9
- package/kits/infografico/receita.json +0 -21
- package/kits/infografico/regras/area-segura.md +0 -17
- package/kits/infografico/regras/cor.md +0 -15
- package/kits/infografico/regras/movimento.md +0 -20
- package/kits/infografico/regras/ritmo.md +0 -15
- package/kits/infografico/regras/som.md +0 -20
- package/kits/infografico/regras/tipografia.md +0 -16
- package/kits/isometrico/assets/ASSETS.md +0 -18
- package/kits/isometrico/elementos/AssinaturaMarca.tsx +0 -24
- package/kits/isometrico/elementos/BlocosMontando.tsx +0 -36
- package/kits/isometrico/elementos/Camera.tsx +0 -23
- package/kits/isometrico/elementos/Cena.tsx +0 -46
- package/kits/isometrico/elementos/CidadeDeDados.tsx +0 -33
- package/kits/isometrico/elementos/Fundo.tsx +0 -13
- package/kits/isometrico/elementos/LegendaPlaca.tsx +0 -18
- package/kits/isometrico/elementos/Montagem.tsx +0 -60
- package/kits/isometrico/elementos/RedeDeBlocos.tsx +0 -41
- package/kits/isometrico/elementos/Som.tsx +0 -39
- package/kits/isometrico/elementos/TextoNoChao.tsx +0 -28
- package/kits/isometrico/elementos/base.ts +0 -86
- package/kits/isometrico/elementos/index.ts +0 -16
- package/kits/isometrico/exemplos/logo-nodo.svg +0 -1
- package/kits/isometrico/exemplos/plano.json +0 -433
- package/kits/isometrico/exemplos/roteiro.md +0 -20
- package/kits/isometrico/preview.tsx +0 -12
- package/kits/isometrico/receita.json +0 -155
- package/kits/isometrico/regras/area-segura.md +0 -13
- package/kits/isometrico/regras/cor.md +0 -18
- package/kits/isometrico/regras/movimento.md +0 -16
- package/kits/isometrico/regras/ritmo.md +0 -13
- package/kits/isometrico/regras/som.md +0 -18
- package/kits/isometrico/regras/tipografia.md +0 -12
- package/kits/jornal/assets/ASSETS.md +0 -24
- package/kits/jornal/elementos/AssinaturaMarca.tsx +0 -25
- package/kits/jornal/elementos/Cabecalho.tsx +0 -21
- package/kits/jornal/elementos/Carimbo.tsx +0 -18
- package/kits/jornal/elementos/Cena.tsx +0 -41
- package/kits/jornal/elementos/Colunas.tsx +0 -24
- package/kits/jornal/elementos/FotoMeiaTinta.tsx +0 -20
- package/kits/jornal/elementos/Fundo.tsx +0 -18
- package/kits/jornal/elementos/JornalGirando.tsx +0 -27
- package/kits/jornal/elementos/Manchete.tsx +0 -30
- package/kits/jornal/elementos/Montagem.tsx +0 -61
- package/kits/jornal/elementos/Som.tsx +0 -38
- package/kits/jornal/elementos/Ticker.tsx +0 -19
- package/kits/jornal/elementos/base.ts +0 -76
- package/kits/jornal/elementos/index.ts +0 -17
- package/kits/jornal/exemplos/fotos/foto-03.jpg +0 -0
- package/kits/jornal/exemplos/fotos/foto-07.jpg +0 -0
- package/kits/jornal/exemplos/logo-esquina.svg +0 -1
- package/kits/jornal/exemplos/plano.json +0 -48
- package/kits/jornal/exemplos/roteiro.md +0 -19
- package/kits/jornal/preview.tsx +0 -17
- package/kits/jornal/receita.json +0 -170
- package/kits/jornal/regras/area-segura.md +0 -19
- package/kits/jornal/regras/cor.md +0 -14
- package/kits/jornal/regras/movimento.md +0 -16
- package/kits/jornal/regras/ritmo.md +0 -15
- package/kits/jornal/regras/som.md +0 -21
- package/kits/jornal/regras/tipografia.md +0 -17
- package/kits/legenda-viva/assets/ASSETS.md +0 -23
- package/kits/legenda-viva/elementos/AssinaturaMarca.tsx +0 -29
- package/kits/legenda-viva/elementos/Cena.tsx +0 -41
- package/kits/legenda-viva/elementos/ChipTema.tsx +0 -19
- package/kits/legenda-viva/elementos/Fundo.tsx +0 -6
- package/kits/legenda-viva/elementos/LegendaCaixa.tsx +0 -36
- package/kits/legenda-viva/elementos/LegendaPalavra.tsx +0 -32
- package/kits/legenda-viva/elementos/Montagem.tsx +0 -59
- package/kits/legenda-viva/elementos/OndaVoz.tsx +0 -23
- package/kits/legenda-viva/elementos/PalavraGigante.tsx +0 -18
- package/kits/legenda-viva/elementos/QuadroFalante.tsx +0 -17
- package/kits/legenda-viva/elementos/Som.tsx +0 -38
- package/kits/legenda-viva/elementos/base.ts +0 -73
- package/kits/legenda-viva/elementos/index.ts +0 -16
- package/kits/legenda-viva/exemplos/fotos/foto-01.jpg +0 -0
- package/kits/legenda-viva/exemplos/fotos/foto-02.jpg +0 -0
- package/kits/legenda-viva/exemplos/fotos/foto-03.jpg +0 -0
- package/kits/legenda-viva/exemplos/fotos/foto-05.jpg +0 -0
- package/kits/legenda-viva/exemplos/logo-dica.svg +0 -1
- package/kits/legenda-viva/exemplos/plano.json +0 -45
- package/kits/legenda-viva/exemplos/roteiro.md +0 -18
- package/kits/legenda-viva/preview.tsx +0 -19
- package/kits/legenda-viva/receita.json +0 -171
- package/kits/legenda-viva/regras/area-segura.md +0 -19
- package/kits/legenda-viva/regras/cor.md +0 -14
- package/kits/legenda-viva/regras/movimento.md +0 -16
- package/kits/legenda-viva/regras/ritmo.md +0 -15
- package/kits/legenda-viva/regras/som.md +0 -21
- package/kits/legenda-viva/regras/tipografia.md +0 -16
- package/kits/luxo/assets/ASSETS.md +0 -20
- package/kits/luxo/elementos/Cena.tsx +0 -36
- package/kits/luxo/elementos/ConviteOuro.tsx +0 -34
- package/kits/luxo/elementos/Fundo.tsx +0 -26
- package/kits/luxo/elementos/LegendaFina.tsx +0 -25
- package/kits/luxo/elementos/LinhaOuro.tsx +0 -24
- package/kits/luxo/elementos/MolduraArco.tsx +0 -36
- package/kits/luxo/elementos/Monograma.tsx +0 -35
- package/kits/luxo/elementos/Montagem.tsx +0 -59
- package/kits/luxo/elementos/Som.tsx +0 -40
- package/kits/luxo/elementos/TituloSerifa.tsx +0 -35
- package/kits/luxo/elementos/base.ts +0 -85
- package/kits/luxo/elementos/index.ts +0 -15
- package/kits/luxo/exemplos/fotos/foto-07.jpg +0 -0
- package/kits/luxo/exemplos/fotos/foto-08.jpg +0 -0
- package/kits/luxo/exemplos/plano.json +0 -145
- package/kits/luxo/exemplos/roteiro.md +0 -18
- package/kits/luxo/preview.tsx +0 -13
- package/kits/luxo/receita.json +0 -18
- package/kits/luxo/regras/area-segura.md +0 -16
- package/kits/luxo/regras/cor.md +0 -16
- package/kits/luxo/regras/movimento.md +0 -19
- package/kits/luxo/regras/ritmo.md +0 -14
- package/kits/luxo/regras/som.md +0 -21
- package/kits/luxo/regras/tipografia.md +0 -17
- package/kits/mapa/assets/ASSETS.md +0 -20
- package/kits/mapa/elementos/CartaoEndereco.tsx +0 -40
- package/kits/mapa/elementos/Cena.tsx +0 -41
- package/kits/mapa/elementos/ChipTempo.tsx +0 -29
- package/kits/mapa/elementos/Fundo.tsx +0 -25
- package/kits/mapa/elementos/MapaBase.tsx +0 -63
- package/kits/mapa/elementos/Montagem.tsx +0 -59
- package/kits/mapa/elementos/Pino.tsx +0 -38
- package/kits/mapa/elementos/RotaAnimada.tsx +0 -38
- package/kits/mapa/elementos/Som.tsx +0 -41
- package/kits/mapa/elementos/TituloLocal.tsx +0 -38
- package/kits/mapa/elementos/base.ts +0 -89
- package/kits/mapa/elementos/index.ts +0 -15
- package/kits/mapa/exemplos/plano.json +0 -48
- package/kits/mapa/exemplos/roteiro.md +0 -19
- package/kits/mapa/preview.tsx +0 -9
- package/kits/mapa/receita.json +0 -21
- package/kits/mapa/regras/area-segura.md +0 -15
- package/kits/mapa/regras/cor.md +0 -18
- package/kits/mapa/regras/movimento.md +0 -21
- package/kits/mapa/regras/ritmo.md +0 -15
- package/kits/mapa/regras/som.md +0 -21
- package/kits/mapa/regras/tipografia.md +0 -16
- package/kits/massinha/assets/ASSETS.md +0 -18
- package/kits/massinha/elementos/AssinaturaMarca.tsx +0 -20
- package/kits/massinha/elementos/BichinhoMassa.tsx +0 -30
- package/kits/massinha/elementos/BolasMassa.tsx +0 -25
- package/kits/massinha/elementos/Camera.tsx +0 -21
- package/kits/massinha/elementos/Cena.tsx +0 -36
- package/kits/massinha/elementos/FormaMassa.tsx +0 -23
- package/kits/massinha/elementos/Fundo.tsx +0 -12
- package/kits/massinha/elementos/ListaMassa.tsx +0 -19
- package/kits/massinha/elementos/Montagem.tsx +0 -56
- package/kits/massinha/elementos/Overlay.tsx +0 -11
- package/kits/massinha/elementos/PlacaMassa.tsx +0 -24
- package/kits/massinha/elementos/Som.tsx +0 -30
- package/kits/massinha/elementos/TituloMassa.tsx +0 -31
- package/kits/massinha/elementos/base.ts +0 -79
- package/kits/massinha/elementos/index.ts +0 -17
- package/kits/massinha/exemplos/plano.json +0 -220
- package/kits/massinha/exemplos/roteiro.md +0 -20
- package/kits/massinha/preview.tsx +0 -12
- package/kits/massinha/receita.json +0 -170
- package/kits/massinha/regras/area-segura.md +0 -15
- package/kits/massinha/regras/cor.md +0 -18
- package/kits/massinha/regras/movimento.md +0 -17
- package/kits/massinha/regras/ritmo.md +0 -15
- package/kits/massinha/regras/som.md +0 -17
- package/kits/massinha/regras/tipografia.md +0 -18
- package/kits/memphis/assets/ASSETS.md +0 -18
- package/kits/memphis/elementos/AssinaturaMarca.tsx +0 -20
- package/kits/memphis/elementos/Camera.tsx +0 -21
- package/kits/memphis/elementos/CartaoMemphis.tsx +0 -16
- package/kits/memphis/elementos/Cena.tsx +0 -36
- package/kits/memphis/elementos/FitaMarquee.tsx +0 -21
- package/kits/memphis/elementos/FormasMemphis.tsx +0 -46
- package/kits/memphis/elementos/Fundo.tsx +0 -15
- package/kits/memphis/elementos/ListaPilulas.tsx +0 -17
- package/kits/memphis/elementos/Montagem.tsx +0 -56
- package/kits/memphis/elementos/NumeroGigante.tsx +0 -19
- package/kits/memphis/elementos/Overlay.tsx +0 -23
- package/kits/memphis/elementos/Som.tsx +0 -30
- package/kits/memphis/elementos/TituloMemphis.tsx +0 -28
- package/kits/memphis/elementos/base.ts +0 -78
- package/kits/memphis/elementos/index.ts +0 -17
- package/kits/memphis/exemplos/plano.json +0 -314
- package/kits/memphis/exemplos/roteiro.md +0 -20
- package/kits/memphis/preview.tsx +0 -12
- package/kits/memphis/receita.json +0 -174
- package/kits/memphis/regras/area-segura.md +0 -14
- package/kits/memphis/regras/cor.md +0 -17
- package/kits/memphis/regras/movimento.md +0 -18
- package/kits/memphis/regras/ritmo.md +0 -15
- package/kits/memphis/regras/som.md +0 -18
- package/kits/memphis/regras/tipografia.md +0 -19
- package/kits/metal-liquido/assets/ASSETS.md +0 -21
- package/kits/metal-liquido/elementos/AnelCromo.tsx +0 -28
- package/kits/metal-liquido/elementos/AssinaturaMarca.tsx +0 -26
- package/kits/metal-liquido/elementos/BolhasCromadas.tsx +0 -53
- package/kits/metal-liquido/elementos/Cena.tsx +0 -48
- package/kits/metal-liquido/elementos/EsferaCromo.tsx +0 -32
- package/kits/metal-liquido/elementos/Fundo.tsx +0 -20
- package/kits/metal-liquido/elementos/Montagem.tsx +0 -67
- package/kits/metal-liquido/elementos/PilulaCromo.tsx +0 -23
- package/kits/metal-liquido/elementos/Som.tsx +0 -33
- package/kits/metal-liquido/elementos/TituloCromo.tsx +0 -32
- package/kits/metal-liquido/elementos/base.ts +0 -94
- package/kits/metal-liquido/elementos/index.ts +0 -15
- package/kits/metal-liquido/exemplos/logo-mercurio.svg +0 -1
- package/kits/metal-liquido/exemplos/plano.json +0 -48
- package/kits/metal-liquido/exemplos/roteiro.md +0 -20
- package/kits/metal-liquido/preview.tsx +0 -12
- package/kits/metal-liquido/receita.json +0 -173
- package/kits/metal-liquido/regras/area-segura.md +0 -16
- package/kits/metal-liquido/regras/cor.md +0 -23
- package/kits/metal-liquido/regras/movimento.md +0 -18
- package/kits/metal-liquido/regras/ritmo.md +0 -14
- package/kits/metal-liquido/regras/som.md +0 -20
- package/kits/metal-liquido/regras/tipografia.md +0 -15
- package/kits/minimal/assets/ASSETS.md +0 -19
- package/kits/minimal/elementos/Cena.tsx +0 -39
- package/kits/minimal/elementos/FormaMorph.tsx +0 -44
- package/kits/minimal/elementos/FraseUnica.tsx +0 -33
- package/kits/minimal/elementos/Fundo.tsx +0 -20
- package/kits/minimal/elementos/LinhaFina.tsx +0 -24
- package/kits/minimal/elementos/Montagem.tsx +0 -59
- package/kits/minimal/elementos/NumeroSolo.tsx +0 -33
- package/kits/minimal/elementos/PontoMovel.tsx +0 -27
- package/kits/minimal/elementos/RodapeMinimal.tsx +0 -26
- package/kits/minimal/elementos/Som.tsx +0 -40
- package/kits/minimal/elementos/base.ts +0 -80
- package/kits/minimal/elementos/index.ts +0 -15
- package/kits/minimal/exemplos/plano.json +0 -48
- package/kits/minimal/exemplos/roteiro.md +0 -19
- package/kits/minimal/preview.tsx +0 -9
- package/kits/minimal/receita.json +0 -21
- package/kits/minimal/regras/area-segura.md +0 -15
- package/kits/minimal/regras/cor.md +0 -12
- package/kits/minimal/regras/movimento.md +0 -20
- package/kits/minimal/regras/ritmo.md +0 -15
- package/kits/minimal/regras/som.md +0 -21
- package/kits/minimal/regras/tipografia.md +0 -15
- package/kits/neon-cidade/assets/ASSETS.md +0 -21
- package/kits/neon-cidade/elementos/AssinaturaMarca.tsx +0 -24
- package/kits/neon-cidade/elementos/CaixaLuminosa.tsx +0 -40
- package/kits/neon-cidade/elementos/Cena.tsx +0 -48
- package/kits/neon-cidade/elementos/Chuva.tsx +0 -23
- package/kits/neon-cidade/elementos/FormaNeon.tsx +0 -42
- package/kits/neon-cidade/elementos/Fundo.tsx +0 -18
- package/kits/neon-cidade/elementos/Horizonte.tsx +0 -34
- package/kits/neon-cidade/elementos/LetreiroNeon.tsx +0 -46
- package/kits/neon-cidade/elementos/Montagem.tsx +0 -67
- package/kits/neon-cidade/elementos/Som.tsx +0 -33
- package/kits/neon-cidade/elementos/base.ts +0 -100
- package/kits/neon-cidade/elementos/index.ts +0 -15
- package/kits/neon-cidade/exemplos/logo-fenix.svg +0 -1
- package/kits/neon-cidade/exemplos/plano.json +0 -50
- package/kits/neon-cidade/exemplos/roteiro.md +0 -20
- package/kits/neon-cidade/preview.tsx +0 -12
- package/kits/neon-cidade/receita.json +0 -151
- package/kits/neon-cidade/regras/area-segura.md +0 -18
- package/kits/neon-cidade/regras/cor.md +0 -23
- package/kits/neon-cidade/regras/movimento.md +0 -18
- package/kits/neon-cidade/regras/ritmo.md +0 -14
- package/kits/neon-cidade/regras/som.md +0 -20
- package/kits/neon-cidade/regras/tipografia.md +0 -15
- package/kits/notion-editorial/assets/ASSETS.md +0 -19
- package/kits/notion-editorial/elementos/AssinaturaMarca.tsx +0 -20
- package/kits/notion-editorial/elementos/BlocoNota.tsx +0 -38
- package/kits/notion-editorial/elementos/Camera.tsx +0 -23
- package/kits/notion-editorial/elementos/Cena.tsx +0 -46
- package/kits/notion-editorial/elementos/Diagrama.tsx +0 -29
- package/kits/notion-editorial/elementos/Fundo.tsx +0 -12
- package/kits/notion-editorial/elementos/Montagem.tsx +0 -60
- package/kits/notion-editorial/elementos/PassosNumerados.tsx +0 -23
- package/kits/notion-editorial/elementos/RabiscoIcone.tsx +0 -33
- package/kits/notion-editorial/elementos/Som.tsx +0 -39
- package/kits/notion-editorial/elementos/TextoSerifa.tsx +0 -53
- package/kits/notion-editorial/elementos/base.ts +0 -87
- package/kits/notion-editorial/elementos/index.ts +0 -16
- package/kits/notion-editorial/exemplos/logo-pauta.svg +0 -1
- package/kits/notion-editorial/exemplos/plano.json +0 -254
- package/kits/notion-editorial/exemplos/roteiro.md +0 -20
- package/kits/notion-editorial/preview.tsx +0 -12
- package/kits/notion-editorial/receita.json +0 -165
- package/kits/notion-editorial/regras/area-segura.md +0 -13
- package/kits/notion-editorial/regras/cor.md +0 -15
- package/kits/notion-editorial/regras/movimento.md +0 -16
- package/kits/notion-editorial/regras/ritmo.md +0 -14
- package/kits/notion-editorial/regras/som.md +0 -18
- package/kits/notion-editorial/regras/tipografia.md +0 -15
- package/kits/papel-recortado/assets/ASSETS.md +0 -18
- package/kits/papel-recortado/elementos/CamadaPapel.tsx +0 -81
- package/kits/papel-recortado/elementos/Camera.tsx +0 -28
- package/kits/papel-recortado/elementos/CartaoCamadas.tsx +0 -38
- package/kits/papel-recortado/elementos/Cena.tsx +0 -29
- package/kits/papel-recortado/elementos/EtiquetaPapel.tsx +0 -40
- package/kits/papel-recortado/elementos/Fita.tsx +0 -21
- package/kits/papel-recortado/elementos/FolhaPopUp.tsx +0 -49
- package/kits/papel-recortado/elementos/Fundo.tsx +0 -10
- package/kits/papel-recortado/elementos/LetrasRecortadas.tsx +0 -48
- package/kits/papel-recortado/elementos/MolduraPapel.tsx +0 -12
- package/kits/papel-recortado/elementos/Montagem.tsx +0 -42
- package/kits/papel-recortado/elementos/Som.tsx +0 -30
- package/kits/papel-recortado/elementos/base.ts +0 -51
- package/kits/papel-recortado/elementos/index.ts +0 -15
- package/kits/papel-recortado/exemplos/plano.json +0 -410
- package/kits/papel-recortado/exemplos/roteiro.md +0 -13
- package/kits/papel-recortado/preview.tsx +0 -9
- package/kits/papel-recortado/receita.json +0 -14
- package/kits/papel-recortado/regras/area-segura.md +0 -13
- package/kits/papel-recortado/regras/cor.md +0 -16
- package/kits/papel-recortado/regras/movimento.md +0 -17
- package/kits/papel-recortado/regras/ritmo.md +0 -13
- package/kits/papel-recortado/regras/som.md +0 -17
- package/kits/papel-recortado/regras/tipografia.md +0 -12
- package/kits/pixel/assets/ASSETS.md +0 -18
- package/kits/pixel/elementos/AssinaturaMarca.tsx +0 -18
- package/kits/pixel/elementos/CaixaDialogo.tsx +0 -22
- package/kits/pixel/elementos/Camera.tsx +0 -21
- package/kits/pixel/elementos/Cena.tsx +0 -36
- package/kits/pixel/elementos/ChuvaDeSprites.tsx +0 -15
- package/kits/pixel/elementos/Fundo.tsx +0 -23
- package/kits/pixel/elementos/HudPlacar.tsx +0 -19
- package/kits/pixel/elementos/MenuPixel.tsx +0 -19
- package/kits/pixel/elementos/Montagem.tsx +0 -56
- package/kits/pixel/elementos/Overlay.tsx +0 -14
- package/kits/pixel/elementos/Som.tsx +0 -30
- package/kits/pixel/elementos/Sprite.tsx +0 -33
- package/kits/pixel/elementos/TituloPixel.tsx +0 -31
- package/kits/pixel/elementos/base.ts +0 -79
- package/kits/pixel/elementos/index.ts +0 -17
- package/kits/pixel/exemplos/plano.json +0 -309
- package/kits/pixel/exemplos/roteiro.md +0 -20
- package/kits/pixel/preview.tsx +0 -12
- package/kits/pixel/receita.json +0 -175
- package/kits/pixel/regras/area-segura.md +0 -14
- package/kits/pixel/regras/cor.md +0 -17
- package/kits/pixel/regras/movimento.md +0 -18
- package/kits/pixel/regras/ritmo.md +0 -15
- package/kits/pixel/regras/som.md +0 -18
- package/kits/pixel/regras/tipografia.md +0 -18
- package/kits/pontos-3d/assets/ASSETS.md +0 -21
- package/kits/pontos-3d/elementos/AssinaturaMarca.tsx +0 -23
- package/kits/pontos-3d/elementos/Cena.tsx +0 -48
- package/kits/pontos-3d/elementos/Contador.tsx +0 -32
- package/kits/pontos-3d/elementos/Fundo.tsx +0 -20
- package/kits/pontos-3d/elementos/Montagem.tsx +0 -67
- package/kits/pontos-3d/elementos/NuvemDePontos.tsx +0 -84
- package/kits/pontos-3d/elementos/RotuloPonto.tsx +0 -32
- package/kits/pontos-3d/elementos/Som.tsx +0 -33
- package/kits/pontos-3d/elementos/TextoDePontos.tsx +0 -55
- package/kits/pontos-3d/elementos/TituloSora.tsx +0 -36
- package/kits/pontos-3d/elementos/base.ts +0 -92
- package/kits/pontos-3d/elementos/index.ts +0 -15
- package/kits/pontos-3d/exemplos/logo-malha.svg +0 -1
- package/kits/pontos-3d/exemplos/plano.json +0 -46
- package/kits/pontos-3d/exemplos/roteiro.md +0 -20
- package/kits/pontos-3d/preview.tsx +0 -12
- package/kits/pontos-3d/receita.json +0 -153
- package/kits/pontos-3d/regras/area-segura.md +0 -17
- package/kits/pontos-3d/regras/cor.md +0 -21
- package/kits/pontos-3d/regras/movimento.md +0 -19
- package/kits/pontos-3d/regras/ritmo.md +0 -14
- package/kits/pontos-3d/regras/som.md +0 -20
- package/kits/pontos-3d/regras/tipografia.md +0 -16
- package/kits/produto-3d/assets/ASSETS.md +0 -18
- package/kits/produto-3d/elementos/AssinaturaMarca.tsx +0 -28
- package/kits/produto-3d/elementos/Camera.tsx +0 -23
- package/kits/produto-3d/elementos/Cena.tsx +0 -55
- package/kits/produto-3d/elementos/Fundo.tsx +0 -45
- package/kits/produto-3d/elementos/Montagem.tsx +0 -53
- package/kits/produto-3d/elementos/NumeroDestaque.tsx +0 -35
- package/kits/produto-3d/elementos/Produto3D.tsx +0 -144
- package/kits/produto-3d/elementos/RotuloChamada.tsx +0 -43
- package/kits/produto-3d/elementos/Som.tsx +0 -39
- package/kits/produto-3d/elementos/TituloMinimo.tsx +0 -45
- package/kits/produto-3d/elementos/VarreduraLuz.tsx +0 -22
- package/kits/produto-3d/elementos/base.ts +0 -109
- package/kits/produto-3d/elementos/index.ts +0 -13
- package/kits/produto-3d/exemplos/plano.json +0 -53
- package/kits/produto-3d/exemplos/roteiro.md +0 -15
- package/kits/produto-3d/preview.tsx +0 -9
- package/kits/produto-3d/receita.json +0 -16
- package/kits/produto-3d/regras/area-segura.md +0 -14
- package/kits/produto-3d/regras/cor.md +0 -20
- package/kits/produto-3d/regras/movimento.md +0 -19
- package/kits/produto-3d/regras/ritmo.md +0 -15
- package/kits/produto-3d/regras/som.md +0 -18
- package/kits/produto-3d/regras/tipografia.md +0 -13
- package/kits/quadro-giz/assets/ASSETS.md +0 -18
- package/kits/quadro-giz/elementos/ApagadorVarrendo.tsx +0 -32
- package/kits/quadro-giz/elementos/AssinaturaMarca.tsx +0 -20
- package/kits/quadro-giz/elementos/Camera.tsx +0 -21
- package/kits/quadro-giz/elementos/CartaoGiz.tsx +0 -25
- package/kits/quadro-giz/elementos/Cena.tsx +0 -36
- package/kits/quadro-giz/elementos/ContaNoQuadro.tsx +0 -34
- package/kits/quadro-giz/elementos/DesenhoGiz.tsx +0 -29
- package/kits/quadro-giz/elementos/Fundo.tsx +0 -21
- package/kits/quadro-giz/elementos/ListaGiz.tsx +0 -21
- package/kits/quadro-giz/elementos/Montagem.tsx +0 -56
- package/kits/quadro-giz/elementos/Overlay.tsx +0 -12
- package/kits/quadro-giz/elementos/Som.tsx +0 -30
- package/kits/quadro-giz/elementos/TituloGiz.tsx +0 -29
- package/kits/quadro-giz/elementos/base.ts +0 -78
- package/kits/quadro-giz/elementos/index.ts +0 -17
- package/kits/quadro-giz/elementos/traco.ts +0 -9
- package/kits/quadro-giz/exemplos/plano.json +0 -237
- package/kits/quadro-giz/exemplos/roteiro.md +0 -20
- package/kits/quadro-giz/preview.tsx +0 -12
- package/kits/quadro-giz/receita.json +0 -193
- package/kits/quadro-giz/regras/area-segura.md +0 -15
- package/kits/quadro-giz/regras/cor.md +0 -17
- package/kits/quadro-giz/regras/movimento.md +0 -18
- package/kits/quadro-giz/regras/ritmo.md +0 -16
- package/kits/quadro-giz/regras/som.md +0 -18
- package/kits/quadro-giz/regras/tipografia.md +0 -19
- package/kits/rabisco/assets/ASSETS.md +0 -18
- package/kits/rabisco/elementos/AssinaturaMarca.tsx +0 -21
- package/kits/rabisco/elementos/Bonequinho.tsx +0 -31
- package/kits/rabisco/elementos/Camera.tsx +0 -21
- package/kits/rabisco/elementos/CartaoRabiscado.tsx +0 -27
- package/kits/rabisco/elementos/Cena.tsx +0 -36
- package/kits/rabisco/elementos/Fundo.tsx +0 -17
- package/kits/rabisco/elementos/ListaRabiscada.tsx +0 -23
- package/kits/rabisco/elementos/Montagem.tsx +0 -55
- package/kits/rabisco/elementos/Som.tsx +0 -30
- package/kits/rabisco/elementos/TituloRabisco.tsx +0 -28
- package/kits/rabisco/elementos/TracoDesenhando.tsx +0 -31
- package/kits/rabisco/elementos/base.ts +0 -76
- package/kits/rabisco/elementos/index.ts +0 -16
- package/kits/rabisco/elementos/traco.ts +0 -10
- package/kits/rabisco/exemplos/plano.json +0 -238
- package/kits/rabisco/exemplos/roteiro.md +0 -20
- package/kits/rabisco/preview.tsx +0 -12
- package/kits/rabisco/receita.json +0 -171
- package/kits/rabisco/regras/area-segura.md +0 -14
- package/kits/rabisco/regras/cor.md +0 -15
- package/kits/rabisco/regras/movimento.md +0 -18
- package/kits/rabisco/regras/ritmo.md +0 -15
- package/kits/rabisco/regras/som.md +0 -17
- package/kits/rabisco/regras/tipografia.md +0 -18
- package/kits/retro-70/assets/ASSETS.md +0 -23
- package/kits/retro-70/elementos/ArcoListras.tsx +0 -25
- package/kits/retro-70/elementos/AssinaturaMarca.tsx +0 -21
- package/kits/retro-70/elementos/CartaoData.tsx +0 -24
- package/kits/retro-70/elementos/Cena.tsx +0 -41
- package/kits/retro-70/elementos/FaixaOnda.tsx +0 -27
- package/kits/retro-70/elementos/Flor70.tsx +0 -25
- package/kits/retro-70/elementos/FotoArredondada.tsx +0 -19
- package/kits/retro-70/elementos/Fundo.tsx +0 -11
- package/kits/retro-70/elementos/Montagem.tsx +0 -60
- package/kits/retro-70/elementos/RaiosDeSol.tsx +0 -27
- package/kits/retro-70/elementos/Som.tsx +0 -38
- package/kits/retro-70/elementos/TituloGordo.tsx +0 -28
- package/kits/retro-70/elementos/base.ts +0 -73
- package/kits/retro-70/elementos/index.ts +0 -17
- package/kits/retro-70/exemplos/fotos/foto-02.jpg +0 -0
- package/kits/retro-70/exemplos/fotos/foto-03.jpg +0 -0
- package/kits/retro-70/exemplos/logo-girassol.svg +0 -1
- package/kits/retro-70/exemplos/plano.json +0 -50
- package/kits/retro-70/exemplos/roteiro.md +0 -19
- package/kits/retro-70/preview.tsx +0 -17
- package/kits/retro-70/receita.json +0 -172
- package/kits/retro-70/regras/area-segura.md +0 -20
- package/kits/retro-70/regras/cor.md +0 -14
- package/kits/retro-70/regras/movimento.md +0 -16
- package/kits/retro-70/regras/ritmo.md +0 -15
- package/kits/retro-70/regras/som.md +0 -21
- package/kits/retro-70/regras/tipografia.md +0 -17
- package/kits/revista/assets/ASSETS.md +0 -24
- package/kits/revista/elementos/AssinaturaMarca.tsx +0 -23
- package/kits/revista/elementos/Cena.tsx +0 -41
- package/kits/revista/elementos/CitacaoGrande.tsx +0 -27
- package/kits/revista/elementos/ColagemFotos.tsx +0 -22
- package/kits/revista/elementos/Folio.tsx +0 -19
- package/kits/revista/elementos/FotoSangrando.tsx +0 -24
- package/kits/revista/elementos/Fundo.tsx +0 -11
- package/kits/revista/elementos/Montagem.tsx +0 -59
- package/kits/revista/elementos/PaginaDupla.tsx +0 -36
- package/kits/revista/elementos/Som.tsx +0 -38
- package/kits/revista/elementos/TituloEditorial.tsx +0 -31
- package/kits/revista/elementos/base.ts +0 -76
- package/kits/revista/elementos/index.ts +0 -16
- package/kits/revista/exemplos/fotos/foto-02.jpg +0 -0
- package/kits/revista/exemplos/fotos/foto-03.jpg +0 -0
- package/kits/revista/exemplos/fotos/foto-05.jpg +0 -0
- package/kits/revista/exemplos/fotos/foto-06.jpg +0 -0
- package/kits/revista/exemplos/fotos/foto-07.jpg +0 -0
- package/kits/revista/exemplos/fotos/foto-08.jpg +0 -0
- package/kits/revista/exemplos/logo-linho.svg +0 -1
- package/kits/revista/exemplos/plano.json +0 -44
- package/kits/revista/exemplos/roteiro.md +0 -19
- package/kits/revista/preview.tsx +0 -21
- package/kits/revista/receita.json +0 -168
- package/kits/revista/regras/area-segura.md +0 -19
- package/kits/revista/regras/cor.md +0 -14
- package/kits/revista/regras/movimento.md +0 -15
- package/kits/revista/regras/ritmo.md +0 -15
- package/kits/revista/regras/som.md +0 -21
- package/kits/revista/regras/tipografia.md +0 -17
- package/kits/risografia/assets/ASSETS.md +0 -18
- package/kits/risografia/elementos/AssinaturaMarca.tsx +0 -21
- package/kits/risografia/elementos/BolaReticula.tsx +0 -26
- package/kits/risografia/elementos/Camera.tsx +0 -21
- package/kits/risografia/elementos/Cena.tsx +0 -36
- package/kits/risografia/elementos/FormaRiso.tsx +0 -24
- package/kits/risografia/elementos/Fundo.tsx +0 -12
- package/kits/risografia/elementos/ListaRiso.tsx +0 -22
- package/kits/risografia/elementos/Montagem.tsx +0 -56
- package/kits/risografia/elementos/NumeroRiso.tsx +0 -21
- package/kits/risografia/elementos/Overlay.tsx +0 -18
- package/kits/risografia/elementos/Som.tsx +0 -30
- package/kits/risografia/elementos/TarjaCarimbo.tsx +0 -20
- package/kits/risografia/elementos/TituloRiso.tsx +0 -26
- package/kits/risografia/elementos/base.ts +0 -73
- package/kits/risografia/elementos/index.ts +0 -17
- package/kits/risografia/exemplos/plano.json +0 -209
- package/kits/risografia/exemplos/roteiro.md +0 -20
- package/kits/risografia/preview.tsx +0 -12
- package/kits/risografia/receita.json +0 -169
- package/kits/risografia/regras/area-segura.md +0 -14
- package/kits/risografia/regras/cor.md +0 -12
- package/kits/risografia/regras/movimento.md +0 -18
- package/kits/risografia/regras/ritmo.md +0 -15
- package/kits/risografia/regras/som.md +0 -17
- package/kits/risografia/regras/tipografia.md +0 -18
- package/kits/saas-linear/assets/ASSETS.md +0 -19
- package/kits/saas-linear/assets/fontes/OFL-Inter.txt +0 -93
- package/kits/saas-linear/assets/fontes/OFL-Newsreader.txt +0 -93
- package/kits/saas-linear/assets/fontes/inter-400.woff2 +0 -0
- package/kits/saas-linear/assets/fontes/inter-600.woff2 +0 -0
- package/kits/saas-linear/assets/fontes/newsreader-400.woff2 +0 -0
- package/kits/saas-linear/elementos/Agenda.tsx +0 -46
- package/kits/saas-linear/elementos/CaixaPrompt.tsx +0 -41
- package/kits/saas-linear/elementos/Camera.tsx +0 -38
- package/kits/saas-linear/elementos/CartoesIntegracao.tsx +0 -57
- package/kits/saas-linear/elementos/Cena.tsx +0 -38
- package/kits/saas-linear/elementos/Cursor.tsx +0 -40
- package/kits/saas-linear/elementos/FraseSerifa.tsx +0 -25
- package/kits/saas-linear/elementos/Fundo.tsx +0 -18
- package/kits/saas-linear/elementos/Marca.tsx +0 -20
- package/kits/saas-linear/elementos/MarcaFinal.tsx +0 -22
- package/kits/saas-linear/elementos/Menu.tsx +0 -46
- package/kits/saas-linear/elementos/Monitor.tsx +0 -28
- package/kits/saas-linear/elementos/Montagem.tsx +0 -67
- package/kits/saas-linear/elementos/Saudacao.tsx +0 -27
- package/kits/saas-linear/elementos/Som.tsx +0 -39
- package/kits/saas-linear/elementos/base.ts +0 -84
- package/kits/saas-linear/elementos/index.ts +0 -21
- package/kits/saas-linear/exemplos/plano.json +0 -459
- package/kits/saas-linear/exemplos/roteiro.md +0 -15
- package/kits/saas-linear/preview.tsx +0 -9
- package/kits/saas-linear/receita.json +0 -32
- package/kits/saas-linear/regras/area-segura.md +0 -17
- package/kits/saas-linear/regras/cor.md +0 -19
- package/kits/saas-linear/regras/movimento.md +0 -20
- package/kits/saas-linear/regras/ritmo.md +0 -14
- package/kits/saas-linear/regras/som.md +0 -16
- package/kits/saas-linear/regras/tipografia.md +0 -17
- package/kits/stripe-ondas/assets/ASSETS.md +0 -18
- package/kits/stripe-ondas/elementos/AssinaturaMarca.tsx +0 -18
- package/kits/stripe-ondas/elementos/Camera.tsx +0 -23
- package/kits/stripe-ondas/elementos/CartaoPagamento.tsx +0 -35
- package/kits/stripe-ondas/elementos/Cena.tsx +0 -46
- package/kits/stripe-ondas/elementos/FaixaDeOndas.tsx +0 -49
- package/kits/stripe-ondas/elementos/Fundo.tsx +0 -11
- package/kits/stripe-ondas/elementos/GraficoOnda.tsx +0 -34
- package/kits/stripe-ondas/elementos/Montagem.tsx +0 -61
- package/kits/stripe-ondas/elementos/PainelCodigo.tsx +0 -36
- package/kits/stripe-ondas/elementos/SelosDeMetodo.tsx +0 -27
- package/kits/stripe-ondas/elementos/Som.tsx +0 -39
- package/kits/stripe-ondas/elementos/TituloLimpo.tsx +0 -27
- package/kits/stripe-ondas/elementos/base.ts +0 -85
- package/kits/stripe-ondas/elementos/index.ts +0 -16
- package/kits/stripe-ondas/exemplos/logo-cais.svg +0 -1
- package/kits/stripe-ondas/exemplos/plano.json +0 -366
- package/kits/stripe-ondas/exemplos/roteiro.md +0 -20
- package/kits/stripe-ondas/preview.tsx +0 -12
- package/kits/stripe-ondas/receita.json +0 -177
- package/kits/stripe-ondas/regras/area-segura.md +0 -16
- package/kits/stripe-ondas/regras/cor.md +0 -17
- package/kits/stripe-ondas/regras/movimento.md +0 -16
- package/kits/stripe-ondas/regras/ritmo.md +0 -14
- package/kits/stripe-ondas/regras/som.md +0 -18
- package/kits/stripe-ondas/regras/tipografia.md +0 -15
- package/kits/suica/assets/ASSETS.md +0 -23
- package/kits/suica/elementos/AssinaturaMarca.tsx +0 -21
- package/kits/suica/elementos/Cena.tsx +0 -41
- package/kits/suica/elementos/DiscoFoto.tsx +0 -20
- package/kits/suica/elementos/Fundo.tsx +0 -16
- package/kits/suica/elementos/GradeFotos.tsx +0 -21
- package/kits/suica/elementos/Indice.tsx +0 -17
- package/kits/suica/elementos/ListaIndice.tsx +0 -25
- package/kits/suica/elementos/Montagem.tsx +0 -60
- package/kits/suica/elementos/NumeroGigante.tsx +0 -21
- package/kits/suica/elementos/Regua.tsx +0 -20
- package/kits/suica/elementos/Som.tsx +0 -38
- package/kits/suica/elementos/TituloGrade.tsx +0 -38
- package/kits/suica/elementos/base.ts +0 -76
- package/kits/suica/elementos/index.ts +0 -17
- package/kits/suica/exemplos/fotos/foto-01.jpg +0 -0
- package/kits/suica/exemplos/fotos/foto-02.jpg +0 -0
- package/kits/suica/exemplos/fotos/foto-03.jpg +0 -0
- package/kits/suica/exemplos/fotos/foto-05.jpg +0 -0
- package/kits/suica/exemplos/fotos/foto-06.jpg +0 -0
- package/kits/suica/exemplos/fotos/foto-07.jpg +0 -0
- package/kits/suica/exemplos/logo-ponto.svg +0 -1
- package/kits/suica/exemplos/plano.json +0 -268
- package/kits/suica/exemplos/roteiro.md +0 -19
- package/kits/suica/preview.tsx +0 -21
- package/kits/suica/receita.json +0 -197
- package/kits/suica/regras/area-segura.md +0 -18
- package/kits/suica/regras/cor.md +0 -13
- package/kits/suica/regras/movimento.md +0 -15
- package/kits/suica/regras/ritmo.md +0 -17
- package/kits/suica/regras/som.md +0 -21
- package/kits/suica/regras/tipografia.md +0 -16
- package/kits/synthwave/assets/ASSETS.md +0 -22
- package/kits/synthwave/elementos/AssinaturaMarca.tsx +0 -26
- package/kits/synthwave/elementos/Cena.tsx +0 -41
- package/kits/synthwave/elementos/Estrelas.tsx +0 -27
- package/kits/synthwave/elementos/Fundo.tsx +0 -20
- package/kits/synthwave/elementos/Montagem.tsx +0 -59
- package/kits/synthwave/elementos/Montanhas.tsx +0 -27
- package/kits/synthwave/elementos/Palmeiras.tsx +0 -30
- package/kits/synthwave/elementos/QuadroHUD.tsx +0 -33
- package/kits/synthwave/elementos/SolListrado.tsx +0 -29
- package/kits/synthwave/elementos/Som.tsx +0 -38
- package/kits/synthwave/elementos/TituloNeon.tsx +0 -30
- package/kits/synthwave/elementos/base.ts +0 -75
- package/kits/synthwave/elementos/index.ts +0 -16
- package/kits/synthwave/exemplos/logo-arcade.svg +0 -1
- package/kits/synthwave/exemplos/plano.json +0 -50
- package/kits/synthwave/exemplos/roteiro.md +0 -19
- package/kits/synthwave/preview.tsx +0 -16
- package/kits/synthwave/receita.json +0 -170
- package/kits/synthwave/regras/area-segura.md +0 -19
- package/kits/synthwave/regras/cor.md +0 -16
- package/kits/synthwave/regras/movimento.md +0 -16
- package/kits/synthwave/regras/ritmo.md +0 -15
- package/kits/synthwave/regras/som.md +0 -21
- package/kits/synthwave/regras/tipografia.md +0 -16
- package/kits/terminal/assets/ASSETS.md +0 -20
- package/kits/terminal/elementos/ArteAscii.tsx +0 -61
- package/kits/terminal/elementos/BarraProgresso.tsx +0 -42
- package/kits/terminal/elementos/BarraStatus.tsx +0 -18
- package/kits/terminal/elementos/BootBios.tsx +0 -41
- package/kits/terminal/elementos/Camera.tsx +0 -23
- package/kits/terminal/elementos/Cena.tsx +0 -25
- package/kits/terminal/elementos/Fundo.tsx +0 -22
- package/kits/terminal/elementos/LinhaComando.tsx +0 -31
- package/kits/terminal/elementos/Monitor.tsx +0 -42
- package/kits/terminal/elementos/Montagem.tsx +0 -52
- package/kits/terminal/elementos/PainelCaixa.tsx +0 -35
- package/kits/terminal/elementos/Som.tsx +0 -32
- package/kits/terminal/elementos/Tela.tsx +0 -25
- package/kits/terminal/elementos/TextoGrande.tsx +0 -35
- package/kits/terminal/elementos/base.ts +0 -67
- package/kits/terminal/elementos/index.ts +0 -16
- package/kits/terminal/exemplos/plano.json +0 -330
- package/kits/terminal/exemplos/roteiro.md +0 -14
- package/kits/terminal/preview.tsx +0 -9
- package/kits/terminal/receita.json +0 -14
- package/kits/terminal/regras/area-segura.md +0 -18
- package/kits/terminal/regras/cor.md +0 -16
- package/kits/terminal/regras/movimento.md +0 -15
- package/kits/terminal/regras/ritmo.md +0 -14
- package/kits/terminal/regras/som.md +0 -17
- package/kits/terminal/regras/tipografia.md +0 -15
- package/kits/tiktok-energia/assets/ASSETS.md +0 -22
- package/kits/tiktok-energia/elementos/AssinaturaMarca.tsx +0 -25
- package/kits/tiktok-energia/elementos/Cena.tsx +0 -48
- package/kits/tiktok-energia/elementos/CorteDeCor.tsx +0 -22
- package/kits/tiktok-energia/elementos/EmojiSticker.tsx +0 -21
- package/kits/tiktok-energia/elementos/FotoSoco.tsx +0 -27
- package/kits/tiktok-energia/elementos/Fundo.tsx +0 -8
- package/kits/tiktok-energia/elementos/Montagem.tsx +0 -67
- package/kits/tiktok-energia/elementos/PalavraSoco.tsx +0 -29
- package/kits/tiktok-energia/elementos/Som.tsx +0 -33
- package/kits/tiktok-energia/elementos/TextoCaixa.tsx +0 -25
- package/kits/tiktok-energia/elementos/base.ts +0 -92
- package/kits/tiktok-energia/elementos/index.ts +0 -15
- package/kits/tiktok-energia/exemplos/fotos/foto-03.jpg +0 -0
- package/kits/tiktok-energia/exemplos/logo-pulo.svg +0 -1
- package/kits/tiktok-energia/exemplos/plano.json +0 -66
- package/kits/tiktok-energia/exemplos/roteiro.md +0 -22
- package/kits/tiktok-energia/preview.tsx +0 -13
- package/kits/tiktok-energia/receita.json +0 -166
- package/kits/tiktok-energia/regras/area-segura.md +0 -19
- package/kits/tiktok-energia/regras/cor.md +0 -20
- package/kits/tiktok-energia/regras/movimento.md +0 -17
- package/kits/tiktok-energia/regras/ritmo.md +0 -15
- package/kits/tiktok-energia/regras/som.md +0 -20
- package/kits/tiktok-energia/regras/tipografia.md +0 -15
- package/kits/tunel/assets/ASSETS.md +0 -21
- package/kits/tunel/elementos/AssinaturaMarca.tsx +0 -22
- package/kits/tunel/elementos/Cena.tsx +0 -48
- package/kits/tunel/elementos/Fundo.tsx +0 -13
- package/kits/tunel/elementos/LinhasDeVelocidade.tsx +0 -25
- package/kits/tunel/elementos/Montagem.tsx +0 -67
- package/kits/tunel/elementos/NumeroGigante.tsx +0 -28
- package/kits/tunel/elementos/PlacaVoadora.tsx +0 -28
- package/kits/tunel/elementos/Som.tsx +0 -33
- package/kits/tunel/elementos/TituloTunel.tsx +0 -32
- package/kits/tunel/elementos/TunelDeFormas.tsx +0 -52
- package/kits/tunel/elementos/base.ts +0 -97
- package/kits/tunel/elementos/index.ts +0 -15
- package/kits/tunel/exemplos/logo-rota21.svg +0 -1
- package/kits/tunel/exemplos/plano.json +0 -51
- package/kits/tunel/exemplos/roteiro.md +0 -20
- package/kits/tunel/preview.tsx +0 -12
- package/kits/tunel/receita.json +0 -153
- package/kits/tunel/regras/area-segura.md +0 -18
- package/kits/tunel/regras/cor.md +0 -21
- package/kits/tunel/regras/movimento.md +0 -17
- package/kits/tunel/regras/ritmo.md +0 -14
- package/kits/tunel/regras/som.md +0 -20
- package/kits/tunel/regras/tipografia.md +0 -15
- package/kits/tutorial-tela/assets/ASSETS.md +0 -20
- package/kits/tutorial-tela/elementos/CameraTela.tsx +0 -29
- package/kits/tutorial-tela/elementos/Cursor.tsx +0 -36
- package/kits/tutorial-tela/elementos/DestaqueCaixa.tsx +0 -17
- package/kits/tutorial-tela/elementos/Fundo.tsx +0 -12
- package/kits/tutorial-tela/elementos/JanelaApp.tsx +0 -81
- package/kits/tutorial-tela/elementos/Montagem.tsx +0 -49
- package/kits/tutorial-tela/elementos/PassoChamada.tsx +0 -22
- package/kits/tutorial-tela/elementos/Som.tsx +0 -41
- package/kits/tutorial-tela/elementos/TeclaAtalho.tsx +0 -29
- package/kits/tutorial-tela/elementos/TituloTela.tsx +0 -30
- package/kits/tutorial-tela/elementos/base.ts +0 -65
- package/kits/tutorial-tela/elementos/index.ts +0 -12
- package/kits/tutorial-tela/exemplos/plano.json +0 -41
- package/kits/tutorial-tela/exemplos/roteiro.md +0 -14
- package/kits/tutorial-tela/preview.tsx +0 -9
- package/kits/tutorial-tela/receita.json +0 -15
- package/kits/tutorial-tela/regras/area-segura.md +0 -13
- package/kits/tutorial-tela/regras/cor.md +0 -17
- package/kits/tutorial-tela/regras/movimento.md +0 -20
- package/kits/tutorial-tela/regras/ritmo.md +0 -24
- package/kits/tutorial-tela/regras/som.md +0 -21
- package/kits/tutorial-tela/regras/tipografia.md +0 -15
- package/kits/ugc-reels/assets/ASSETS.md +0 -22
- package/kits/ugc-reels/elementos/AssinaturaMarca.tsx +0 -28
- package/kits/ugc-reels/elementos/BotaoLink.tsx +0 -24
- package/kits/ugc-reels/elementos/CabecalhoPerfil.tsx +0 -38
- package/kits/ugc-reels/elementos/Cena.tsx +0 -48
- package/kits/ugc-reels/elementos/Comentario.tsx +0 -29
- package/kits/ugc-reels/elementos/Fundo.tsx +0 -8
- package/kits/ugc-reels/elementos/LegendaEmoji.tsx +0 -43
- package/kits/ugc-reels/elementos/Montagem.tsx +0 -69
- package/kits/ugc-reels/elementos/NotaDeMao.tsx +0 -29
- package/kits/ugc-reels/elementos/Reacoes.tsx +0 -26
- package/kits/ugc-reels/elementos/Som.tsx +0 -33
- package/kits/ugc-reels/elementos/VideoCelular.tsx +0 -37
- package/kits/ugc-reels/elementos/base.ts +0 -92
- package/kits/ugc-reels/elementos/index.ts +0 -17
- package/kits/ugc-reels/exemplos/fotos/foto-02.jpg +0 -0
- package/kits/ugc-reels/exemplos/fotos/foto-03.jpg +0 -0
- package/kits/ugc-reels/exemplos/fotos/foto-04.jpg +0 -0
- package/kits/ugc-reels/exemplos/fotos/foto-06.jpg +0 -0
- package/kits/ugc-reels/exemplos/logo-rotina.svg +0 -1
- package/kits/ugc-reels/exemplos/plano.json +0 -54
- package/kits/ugc-reels/exemplos/roteiro.md +0 -20
- package/kits/ugc-reels/preview.tsx +0 -16
- package/kits/ugc-reels/receita.json +0 -147
- package/kits/ugc-reels/regras/area-segura.md +0 -18
- package/kits/ugc-reels/regras/cor.md +0 -22
- package/kits/ugc-reels/regras/movimento.md +0 -19
- package/kits/ugc-reels/regras/ritmo.md +0 -14
- package/kits/ugc-reels/regras/som.md +0 -20
- package/kits/ugc-reels/regras/tipografia.md +0 -16
- package/kits/vercel-mono/assets/ASSETS.md +0 -18
- package/kits/vercel-mono/assets/sons/assinatura.mp3 +0 -0
- package/kits/vercel-mono/assets/sons/clique.mp3 +0 -0
- package/kits/vercel-mono/assets/sons/impacto.mp3 +0 -0
- package/kits/vercel-mono/assets/sons/pop-cartao.mp3 +0 -0
- package/kits/vercel-mono/assets/sons/pop-palavra.mp3 +0 -0
- package/kits/vercel-mono/assets/sons/subida.mp3 +0 -0
- package/kits/vercel-mono/assets/sons/swoosh.mp3 +0 -0
- package/kits/vercel-mono/assets/sons/whoosh-entra.mp3 +0 -0
- package/kits/vercel-mono/assets/sons/whoosh-sai.mp3 +0 -0
- package/kits/vercel-mono/elementos/AssinaturaMarca.tsx +0 -18
- package/kits/vercel-mono/elementos/Camera.tsx +0 -23
- package/kits/vercel-mono/elementos/Cena.tsx +0 -46
- package/kits/vercel-mono/elementos/FaixaOutline.tsx +0 -25
- package/kits/vercel-mono/elementos/Fundo.tsx +0 -6
- package/kits/vercel-mono/elementos/GradeDeNumeros.tsx +0 -27
- package/kits/vercel-mono/elementos/Montagem.tsx +0 -61
- package/kits/vercel-mono/elementos/PalavraMono.tsx +0 -31
- package/kits/vercel-mono/elementos/Quadro.tsx +0 -28
- package/kits/vercel-mono/elementos/Som.tsx +0 -39
- package/kits/vercel-mono/elementos/TerminalComando.tsx +0 -33
- package/kits/vercel-mono/elementos/TrianguloGigante.tsx +0 -27
- package/kits/vercel-mono/elementos/base.ts +0 -82
- package/kits/vercel-mono/elementos/index.ts +0 -16
- package/kits/vercel-mono/exemplos/logo-vetor.svg +0 -1
- package/kits/vercel-mono/exemplos/plano.json +0 -318
- package/kits/vercel-mono/exemplos/roteiro.md +0 -20
- package/kits/vercel-mono/preview.tsx +0 -12
- package/kits/vercel-mono/receita.json +0 -156
- package/kits/vercel-mono/regras/area-segura.md +0 -13
- package/kits/vercel-mono/regras/cor.md +0 -12
- package/kits/vercel-mono/regras/movimento.md +0 -15
- package/kits/vercel-mono/regras/ritmo.md +0 -13
- package/kits/vercel-mono/regras/som.md +0 -18
- package/kits/vercel-mono/regras/tipografia.md +0 -14
- package/kits/vhs-90/assets/ASSETS.md +0 -23
- package/kits/vhs-90/elementos/AssinaturaMarca.tsx +0 -29
- package/kits/vhs-90/elementos/BarrasRastreio.tsx +0 -21
- package/kits/vhs-90/elementos/CapaVHS.tsx +0 -28
- package/kits/vhs-90/elementos/CarimboData.tsx +0 -19
- package/kits/vhs-90/elementos/Cena.tsx +0 -41
- package/kits/vhs-90/elementos/Fundo.tsx +0 -27
- package/kits/vhs-90/elementos/MenuOSD.tsx +0 -27
- package/kits/vhs-90/elementos/Montagem.tsx +0 -60
- package/kits/vhs-90/elementos/Som.tsx +0 -38
- package/kits/vhs-90/elementos/TelaAzul.tsx +0 -29
- package/kits/vhs-90/elementos/TituloFita.tsx +0 -40
- package/kits/vhs-90/elementos/base.ts +0 -75
- package/kits/vhs-90/elementos/index.ts +0 -16
- package/kits/vhs-90/exemplos/fotos/foto-05.jpg +0 -0
- package/kits/vhs-90/exemplos/fotos/foto-07.jpg +0 -0
- package/kits/vhs-90/exemplos/logo-rewind.svg +0 -1
- package/kits/vhs-90/exemplos/plano.json +0 -47
- package/kits/vhs-90/exemplos/roteiro.md +0 -19
- package/kits/vhs-90/preview.tsx +0 -17
- package/kits/vhs-90/receita.json +0 -189
- package/kits/vhs-90/regras/area-segura.md +0 -18
- package/kits/vhs-90/regras/cor.md +0 -16
- package/kits/vhs-90/regras/movimento.md +0 -16
- package/kits/vhs-90/regras/ritmo.md +0 -16
- package/kits/vhs-90/regras/som.md +0 -21
- package/kits/vhs-90/regras/tipografia.md +0 -17
- package/kits/vidro-ios/assets/ASSETS.md +0 -18
- package/kits/vidro-ios/elementos/AssinaturaMarca.tsx +0 -21
- package/kits/vidro-ios/elementos/Camera.tsx +0 -23
- package/kits/vidro-ios/elementos/Cena.tsx +0 -46
- package/kits/vidro-ios/elementos/Fundo.tsx +0 -17
- package/kits/vidro-ios/elementos/IlhaDinamica.tsx +0 -24
- package/kits/vidro-ios/elementos/Montagem.tsx +0 -60
- package/kits/vidro-ios/elementos/PainelControle.tsx +0 -33
- package/kits/vidro-ios/elementos/PilhaNotificacoes.tsx +0 -29
- package/kits/vidro-ios/elementos/Som.tsx +0 -39
- package/kits/vidro-ios/elementos/TituloVidro.tsx +0 -22
- package/kits/vidro-ios/elementos/WidgetsGrade.tsx +0 -34
- package/kits/vidro-ios/elementos/base.ts +0 -87
- package/kits/vidro-ios/elementos/index.ts +0 -16
- package/kits/vidro-ios/elementos/vidro.tsx +0 -20
- package/kits/vidro-ios/exemplos/logo-vento.svg +0 -1
- package/kits/vidro-ios/exemplos/plano.json +0 -288
- package/kits/vidro-ios/exemplos/roteiro.md +0 -20
- package/kits/vidro-ios/preview.tsx +0 -12
- package/kits/vidro-ios/receita.json +0 -170
- package/kits/vidro-ios/regras/area-segura.md +0 -13
- package/kits/vidro-ios/regras/cor.md +0 -16
- package/kits/vidro-ios/regras/movimento.md +0 -16
- package/kits/vidro-ios/regras/ritmo.md +0 -14
- package/kits/vidro-ios/regras/som.md +0 -18
- package/kits/vidro-ios/regras/tipografia.md +0 -15
- package/kits/y2k-cromado/assets/ASSETS.md +0 -23
- package/kits/y2k-cromado/elementos/AssinaturaMarca.tsx +0 -25
- package/kits/y2k-cromado/elementos/Bolhas.tsx +0 -30
- package/kits/y2k-cromado/elementos/Brilhos.tsx +0 -28
- package/kits/y2k-cromado/elementos/CartaoGloss.tsx +0 -26
- package/kits/y2k-cromado/elementos/Cena.tsx +0 -41
- package/kits/y2k-cromado/elementos/FitaMarquee.tsx +0 -20
- package/kits/y2k-cromado/elementos/Fundo.tsx +0 -18
- package/kits/y2k-cromado/elementos/JanelaY2K.tsx +0 -31
- package/kits/y2k-cromado/elementos/Montagem.tsx +0 -60
- package/kits/y2k-cromado/elementos/OrbeCromo.tsx +0 -20
- package/kits/y2k-cromado/elementos/Som.tsx +0 -38
- package/kits/y2k-cromado/elementos/TextoCromo.tsx +0 -34
- package/kits/y2k-cromado/elementos/base.ts +0 -75
- package/kits/y2k-cromado/elementos/index.ts +0 -17
- package/kits/y2k-cromado/exemplos/fotos/foto-02.jpg +0 -0
- package/kits/y2k-cromado/exemplos/fotos/foto-03.jpg +0 -0
- package/kits/y2k-cromado/exemplos/logo-bolha.svg +0 -1
- package/kits/y2k-cromado/exemplos/plano.json +0 -47
- package/kits/y2k-cromado/exemplos/roteiro.md +0 -19
- package/kits/y2k-cromado/preview.tsx +0 -17
- package/kits/y2k-cromado/receita.json +0 -174
- package/kits/y2k-cromado/regras/area-segura.md +0 -19
- package/kits/y2k-cromado/regras/cor.md +0 -16
- package/kits/y2k-cromado/regras/movimento.md +0 -16
- package/kits/y2k-cromado/regras/ritmo.md +0 -15
- package/kits/y2k-cromado/regras/som.md +0 -21
- package/kits/y2k-cromado/regras/tipografia.md +0 -17
- package/lib/act.js +0 -2512
- package/lib/api.js +0 -310
- package/lib/boas-vindas.js +0 -153
- package/lib/catalogo.js +0 -367
- package/lib/checkpoint-git.js +0 -221
- package/lib/checkpoint.js +0 -366
- package/lib/claude-engine.js +0 -673
- package/lib/codex-engine.js +0 -225
- package/lib/comandos-extra.js +0 -553
- package/lib/comandos.js +0 -104
- package/lib/config.js +0 -414
- package/lib/desktop.js +0 -756
- package/lib/editor-pro-maquina.js +0 -165
- package/lib/editor-pro.js +0 -930
- package/lib/entrada.js +0 -1031
- package/lib/entregaveis/cli.js +0 -26
- package/lib/entregaveis/especialistas.js +0 -50
- package/lib/entregaveis/nucleo.js +0 -111
- package/lib/entregaveis/slides.js +0 -221
- package/lib/estudio/acervo.js +0 -418
- package/lib/estudio/assets.js +0 -497
- package/lib/estudio/assinatura.js +0 -108
- package/lib/estudio/conferencia-visual.js +0 -76
- package/lib/estudio/cota.js +0 -157
- package/lib/estudio/diretor.js +0 -392
- package/lib/estudio/editor.js +0 -290
- package/lib/estudio/gosto-descrever.js +0 -87
- package/lib/estudio/gosto.js +0 -608
- package/lib/estudio/identidade.js +0 -560
- package/lib/estudio/index.js +0 -2712
- package/lib/estudio/kit.js +0 -91
- package/lib/estudio/kits-tela.js +0 -199
- package/lib/estudio/kokoro.js +0 -127
- package/lib/estudio/maquina-foto.js +0 -177
- package/lib/estudio/maquina-trilha.js +0 -160
- package/lib/estudio/maquina-voz.js +0 -429
- package/lib/estudio/marca.js +0 -398
- package/lib/estudio/materiais.js +0 -172
- package/lib/estudio/morfar.js +0 -191
- package/lib/estudio/print-site.js +0 -341
- package/lib/estudio/projeto.js +0 -340
- package/lib/estudio/projetos.js +0 -72
- package/lib/exportar-conversa.js +0 -49
- package/lib/headless.js +0 -102
- package/lib/kits-parecidos.js +0 -99
- package/lib/kits-plano.js +0 -557
- package/lib/kits.js +0 -1084
- package/lib/limites.js +0 -100
- package/lib/linha-do-tempo.js +0 -130
- package/lib/local/motor-cli.js +0 -93
- package/lib/local/motor.js +0 -267
- package/lib/local/provedor.js +0 -169
- package/lib/marca-kit.js +0 -312
- package/lib/marketplace.js +0 -189
- package/lib/mcp.js +0 -819
- package/lib/motioncraft.js +0 -67
- package/lib/perigo.js +0 -401
- package/lib/permissao.js +0 -137
- package/lib/sandbox.js +0 -252
- package/lib/skills.js +0 -468
- package/lib/statusline.js +0 -52
- package/lib/tela.js +0 -245
- package/lib/tools.js +0 -1086
- package/lib/ui.js +0 -763
- package/lib/video/analise.js +0 -89
- package/lib/video/projeto.js +0 -133
- package/lib/video/rastrear.js +0 -95
- package/lib/video/render.js +0 -274
- package/lib/video/transcript.js +0 -124
- package/lib/voz-ponte.js +0 -15
- package/lib/voz.js +0 -532
- package/materiais/saas-linear/sons/trilha.mp3 +0 -0
- /package/lib/{comecar.js → cli/comecar.js} +0 -0
- /package/lib/{conta.js → config/conta.js} +0 -0
- /package/lib/{limite.js → config/limite.js} +0 -0
- /package/lib/{protecao.js → permission/protecao.js} +0 -0
- /package/lib/{entregaveis.js → plugin/entregaveis.js} +0 -0
- /package/lib/{estudio → plugin/estudio}/acervo-site.js +0 -0
- /package/lib/{estudio → plugin/estudio}/assinaturas/fluido.json +0 -0
- /package/lib/{estudio → plugin/estudio}/assinaturas/gerativo.json +0 -0
- /package/lib/{estudio → plugin/estudio}/batida.js +0 -0
- /package/lib/{estudio → plugin/estudio}/biblioteca.js +0 -0
- /package/lib/{estudio → plugin/estudio}/camadas.js +0 -0
- /package/lib/{estudio → plugin/estudio}/cena.js +0 -0
- /package/lib/{estudio → plugin/estudio}/cenarios.js +0 -0
- /package/lib/{estudio → plugin/estudio}/cinema.js +0 -0
- /package/lib/{estudio → plugin/estudio}/colecao.js +0 -0
- /package/lib/{estudio → plugin/estudio}/composicao.js +0 -0
- /package/lib/{estudio → plugin/estudio}/conferencia.js +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/fluent-3d.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/noto-animado.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-ad5.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-ae-sem-memoria.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-agent.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-antes-e-agora.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-apresentando-clube.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-bluevisa.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-caught-in-the-fire.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-chat-cliente-satisfeito.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-chatgpt-anuncios.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-claude-dj.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-claude-mcp.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-cleanui.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-clinica-take-unico.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-clinica.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-clube-opener.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-clube.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-codigo.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-distilbook.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-drive-upload.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-dub.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-enxovaly.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-fecha7.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-filatov.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-frame.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-glass.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-letra-em-apps.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-letra-globo-3d.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-letra-nos-apps.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-letra-seis-mundos.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-lula-3.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-morph.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-motion-designer.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-motion-pacote.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-movimento.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-not-like-us.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-pinterest-inspiracao.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-pixel-e-tinta.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-ponte.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-processo-edit-tonal.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-processo-motion-100-ia.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-promo.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-proposito.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-rankhog.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-recursao.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-revelar.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-robo.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-shelby-ep2.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-shelby.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-solar-eclipse.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-soldier.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-som-de-cena.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-spotify-candidatura.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-tda-app.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-tda-ia.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-telegram-chat.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-telegram-ilha.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-tennessee-nike.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-tudo-se-move.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-uiad.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-viralgrow.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-whose-side.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/clube-youtube-inscrever.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/elementos-do-site-em-movimento.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/explainer-narrado.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/lancamento-de-produto.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/motion-so-com-sons.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/titulo-em-after-effects.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos/tour-de-saas.json +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/antes-e-agora/ae/cenas.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/antes-e-agora/assets/fazer_assets.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-em-apps/ae/cenas.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-em-apps/assets/preparar_assets.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-em-apps/assets/svg_para_ae.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/BRIEF-AGENTES.md +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/README.md +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ROTEIRO-CENAS.md +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/A-agenda.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/B-docs.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/C-alttab.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/D-spotify.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/E-notas.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/F-jornal1.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/G-google.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/H-mapa.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/I-imagens.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/J-jornal2.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/K-maps.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/camera-movimentos.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/camera.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/card-spotify.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/digitar.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/jornal-comum.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/letra.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/letra_automatica.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/montagem.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/w-agenda/render_html.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/w-agenda/util.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/w-midia-comum.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/ae/wg-util.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/assets/F-jornal1/render_html.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/assets/render_w-midia.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/assets/w-midia-ferramentas/inclin.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/assets/w-midia-ferramentas/medir_d.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/assets/w-midia-ferramentas/medir_e.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/camera/ajustar_movimentos.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/camera/ancorar.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/camera/assar.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/camera/camera3d_jornal.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/camera/comparar.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/camera/dados_ae_jornal.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/camera/folha_contato.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/camera/homografia_jornal.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/camera/integrar.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/camera/medir_quadro_a_quadro.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/camera/mesa_2d.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/camera/plot_cenas.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/camera/retificar_quadros.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/camera/w-agenda/assar_ab.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/camera/w-agenda/medir_ab.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/camera/wg_ajustar_h.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/camera/wg_corrige_cam.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/camera/wg_ecc_cadeia.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/camera/wg_finalizar_cam.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/camera/wg_mosaico.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/guia-do-metodo/tutorial-lyric-edit-interfaces/01-gramatica-e-roteiro.md +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/guia-do-metodo/tutorial-lyric-edit-interfaces/02-camera.md +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/guia-do-metodo/tutorial-lyric-edit-interfaces/03-montagem-no-ae.md +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/guia-do-metodo/tutorial-lyric-edit-interfaces/04-render-e-conferencia.md +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/guia-do-metodo/tutorial-lyric-edit-interfaces/05-abertura-celular-mergulho.md +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/guia-do-metodo/tutorial-lyric-edit-interfaces.md +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/transicao/atraso_imagem.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/transicao/fundo.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/transicao/juntar.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/transicao/montar.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/transicao/rastreio.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/letra-nos-apps/transicao/sincronia.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/pinterest-inspiracao/ae/cenas.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/pinterest-inspiracao/assets/fazer_assets.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/processo-motion-100-ia/assets/pessoas/figurinha.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/processo-motion-100-ia/comp-a/BRIEF-A.md +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/processo-motion-100-ia/comp-a/audio.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/processo-motion-100-ia/comp-a/confere.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/processo-motion-100-ia/comp-a/dados/tempo-parte1.js +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/processo-motion-100-ia/comp-a/dados/tempo-parte2.js +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/processo-motion-100-ia/comp-a/gerar_emojis.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/processo-motion-100-ia/comp-a/img/filmes/_indice.js +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/processo-motion-100-ia/comp-a/js/base.js +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/processo-motion-100-ia/comp-a/js/main.js +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/processo-motion-100-ia/comp-a/js/p1a.js +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/processo-motion-100-ia/comp-a/js/p1b.js +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/processo-motion-100-ia/comp-a/js/p1c.js +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/processo-motion-100-ia/comp-a/js/p2.js +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/processo-motion-100-ia/comp-a/video.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/processo-motion-100-ia/take-unico/README.md +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/processo-motion-100-ia/take-unico/oraculo_take.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/processo-motion-100-ia/take-unico/render_take.py +0 -0
- /package/lib/{estudio → plugin/estudio}/dados/projetos-ae/processo-motion-100-ia/take-unico/take.js +0 -0
- /package/lib/{estudio → plugin/estudio}/decisao.js +0 -0
- /package/lib/{estudio → plugin/estudio}/edicao.js +0 -0
- /package/lib/{estudio → plugin/estudio}/efeitos-fabrica/brilho-varredura.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/efeitos-fabrica/camadas-empilhadas.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/efeitos-fabrica/cor-inunda.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/efeitos-fabrica/mola-com-peso.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/efeitos-fabrica/peca-impacto-3d.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/efeitos-fabrica/raios-de-luz.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/efeitos-fabrica/risco-multilinha.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/efeitos-fabrica/terminal-digitando.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/efeitos.js +0 -0
- /package/lib/{estudio → plugin/estudio}/effectcraft.js +0 -0
- /package/lib/{estudio → plugin/estudio}/ende.js +0 -0
- /package/lib/{estudio → plugin/estudio}/estilo.js +0 -0
- /package/lib/{estudio → plugin/estudio}/estilos.js +0 -0
- /package/lib/{estudio → plugin/estudio}/exportar.js +0 -0
- /package/lib/{estudio → plugin/estudio}/falantes.js +0 -0
- /package/lib/{estudio → plugin/estudio}/fluido.js +0 -0
- /package/lib/{estudio → plugin/estudio}/gerativo.js +0 -0
- /package/lib/{estudio → plugin/estudio}/glifos.js +0 -0
- /package/lib/{estudio → plugin/estudio}/gosto/tela.html +0 -0
- /package/lib/{estudio → plugin/estudio}/gosto-medir.js +0 -0
- /package/lib/{estudio → plugin/estudio}/gosto-prova.js +0 -0
- /package/lib/{estudio → plugin/estudio}/hibrido.js +0 -0
- /package/lib/{estudio → plugin/estudio}/impacto.js +0 -0
- /package/lib/{estudio → plugin/estudio}/kit/animacao.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/kit/base.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/kit/fluido.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/kit/gerativo.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/kit/index.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/kit/marca.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/kit/mundo.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/kit/natural.js +0 -0
- /package/lib/{estudio → plugin/estudio}/kit/personagem.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/kit/rosto.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/kit/tres.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/kit/vox.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/kit/voxel.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/kit-ae/base.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/kit-ae/cenas.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/kit-ae/guarda.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/kit-ae/primitivas.jsx +0 -0
- /package/lib/{estudio → plugin/estudio}/kits/tela.html +0 -0
- /package/lib/{estudio → plugin/estudio}/lancamento.js +0 -0
- /package/lib/{estudio → plugin/estudio}/legibilidade.js +0 -0
- /package/lib/{estudio → plugin/estudio}/maquina-diretor.js +0 -0
- /package/lib/{estudio → plugin/estudio}/maquina-elementos.js +0 -0
- /package/lib/{estudio → plugin/estudio}/maquina-guarda.js +0 -0
- /package/lib/{estudio → plugin/estudio}/maquina-layout.js +0 -0
- /package/lib/{estudio → plugin/estudio}/maquina-som.js +0 -0
- /package/lib/{estudio → plugin/estudio}/maquina.js +0 -0
- /package/lib/{estudio → plugin/estudio}/margem.js +0 -0
- /package/lib/{estudio → plugin/estudio}/motion.js +0 -0
- /package/lib/{estudio → plugin/estudio}/movimentos.js +0 -0
- /package/lib/{estudio → plugin/estudio}/mundo.js +0 -0
- /package/lib/{estudio → plugin/estudio}/personagem.js +0 -0
- /package/lib/{estudio → plugin/estudio}/plano.js +0 -0
- /package/lib/{estudio → plugin/estudio}/producao.js +0 -0
- /package/lib/{estudio → plugin/estudio}/referencias.js +0 -0
- /package/lib/{estudio → plugin/estudio}/regras-motion.js +0 -0
- /package/lib/{estudio → plugin/estudio}/remotion.js +0 -0
- /package/lib/{estudio → plugin/estudio}/revisor.js +0 -0
- /package/lib/{estudio → plugin/estudio}/ritmo.js +0 -0
- /package/lib/{estudio → plugin/estudio}/sem-narracao.js +0 -0
- /package/lib/{estudio → plugin/estudio}/slides.js +0 -0
- /package/lib/{estudio → plugin/estudio}/sons-leves.js +0 -0
- /package/lib/{estudio → plugin/estudio}/variacao3d.js +0 -0
- /package/lib/{estudio → plugin/estudio}/variedade.js +0 -0
- /package/lib/{estudio → plugin/estudio}/video.js +0 -0
- /package/lib/{estudio → plugin/estudio}/visao/visao.swift +0 -0
- /package/lib/{estudio → plugin/estudio}/visao.js +0 -0
- /package/lib/{estudio → plugin/estudio}/voicestudio.js +0 -0
- /package/lib/{estudio → plugin/estudio}/vox.js +0 -0
- /package/lib/{video → plugin/video}/auto.js +0 -0
- /package/lib/{video → plugin/video}/camadas.js +0 -0
- /package/lib/{video → plugin/video}/cli.js +0 -0
- /package/lib/{video → plugin/video}/conferir-legenda.js +0 -0
- /package/lib/{video → plugin/video}/cor.js +0 -0
- /package/lib/{video → plugin/video}/delta.js +0 -0
- /package/lib/{video → plugin/video}/edits.js +0 -0
- /package/lib/{video → plugin/video}/filters.js +0 -0
- /package/lib/{video → plugin/video}/fx3d/Camadas.jsx +0 -0
- /package/lib/{video → plugin/video}/fx3d/Objetos.jsx +0 -0
- /package/lib/{video → plugin/video}/fx3d/Root.jsx +0 -0
- /package/lib/{video → plugin/video}/fx3d/modelos.jsx +0 -0
- /package/lib/{video → plugin/video}/fx3d.js +0 -0
- /package/lib/{video → plugin/video}/gerados.js +0 -0
- /package/lib/{video → plugin/video}/objetos.js +0 -0
- /package/lib/{video → plugin/video}/ops-fx.js +0 -0
- /package/lib/{video → plugin/video}/ops.js +0 -0
- /package/lib/{video → plugin/video}/paralelo.js +0 -0
- /package/lib/{video → plugin/video}/pedido.js +0 -0
- /package/lib/{video → plugin/video}/rastro.js +0 -0
- /package/lib/{video → plugin/video}/texto.js +0 -0
- /package/lib/{video → plugin/video}/timeline.js +0 -0
- /package/lib/{video → plugin/video}/zoom.js +0 -0
- /package/lib/{local → provider/local}/cerebro.json +0 -0
- /package/lib/{local → provider/local}/entrada.js +0 -0
- /package/lib/{encolheu.js → session/encolheu.js} +0 -0
- /package/lib/{memoria-conversa.js → session/memoria-conversa.js} +0 -0
- /package/lib/{retomar.js → session/retomar.js} +0 -0
- /package/lib/{snapshot.js → session/snapshot.js} +0 -0
- /package/lib/{titulo-conversa.js → session/titulo-conversa.js} +0 -0
- /package/lib/{especialistas.js → skill/especialistas.js} +0 -0
- /package/lib/{personas.js → skill/personas.js} +0 -0
- /package/lib/{portao-skill.js → skill/portao-skill.js} +0 -0
- /package/lib/{casar.js → tool/casar.js} +0 -0
- /package/lib/{markdown.js → tui/markdown.js} +0 -0
- /package/{kits/adesivos/elementos → materiais/adesivos/camera}/Camera.tsx +0 -0
- /package/{kits/adesivos/assets → materiais/adesivos}/fontes/OFL-BowlbyOne.txt +0 -0
- /package/{kits/adesivos/assets → materiais/adesivos}/fontes/OFL-Nunito.txt +0 -0
- /package/{kits/adesivos/assets → materiais/adesivos}/fontes/bowlby-latin.woff2 +0 -0
- /package/{kits/adesivos/assets → materiais/adesivos}/fontes/nunito-latin.woff2 +0 -0
- /package/{kits/adesivos/assets → materiais/adesivos}/sons/assinatura.mp3 +0 -0
- /package/{kits/adesivos/assets → materiais/adesivos}/sons/cola.mp3 +0 -0
- /package/{kits/adesivos/assets → materiais/adesivos}/sons/confete.mp3 +0 -0
- /package/{kits/adesivos/assets → materiais/adesivos}/sons/impacto.mp3 +0 -0
- /package/{kits/adesivos/assets → materiais/adesivos}/sons/palavra.mp3 +0 -0
- /package/{kits/adesivos/assets → materiais/adesivos}/sons/pop.mp3 +0 -0
- /package/{kits/adesivos/assets → materiais/adesivos}/sons/swipe.mp3 +0 -0
- /package/{kits/adesivos/assets → materiais/adesivos}/sons/whoosh.mp3 +0 -0
- /package/{kits/adesivos/assets → materiais/adesivos}/trilha/pop-colorido-112bpm.mp3 +0 -0
- /package/{kits/antes-depois/elementos → materiais/antes-depois/camera}/Camera.tsx +0 -0
- /package/{kits/antes-depois/assets → materiais/antes-depois}/fontes/OFL-ArchivoBlack.txt +0 -0
- /package/{kits/antes-depois/assets → materiais/antes-depois}/fontes/OFL-Manrope.txt +0 -0
- /package/{kits/antes-depois/assets → materiais/antes-depois}/fontes/archivoblack.woff2 +0 -0
- /package/{kits/antes-depois/assets → materiais/antes-depois}/fontes/manrope.woff2 +0 -0
- /package/{kits/antes-depois/assets → materiais/antes-depois}/sons/assinatura.mp3 +0 -0
- /package/{kits/antes-depois/assets → materiais/antes-depois}/sons/clique.mp3 +0 -0
- /package/{kits/antes-depois/assets → materiais/antes-depois}/sons/impacto.mp3 +0 -0
- /package/{kits/antes-depois/assets → materiais/antes-depois}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/antes-depois/assets → materiais/antes-depois}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/antes-depois/assets → materiais/antes-depois}/sons/subida.mp3 +0 -0
- /package/{kits/antes-depois/assets → materiais/antes-depois}/sons/swoosh.mp3 +0 -0
- /package/{kits/antes-depois/assets → materiais/antes-depois}/sons/tick.mp3 +0 -0
- /package/{kits/antes-depois/assets → materiais/antes-depois}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/antes-depois/assets → materiais/antes-depois}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/antes-depois/assets → materiais/antes-depois}/trilha/corte-118bpm.mp3 +0 -0
- /package/{kits/apple-tipografico/assets → materiais/apple-tipografico}/fontes/OFL-Inter.txt +0 -0
- /package/{kits/apple-tipografico/assets → materiais/apple-tipografico}/fontes/inter-latin-500-800.woff2 +0 -0
- /package/{kits/apple-tipografico/elementos → materiais/apple-tipografico/lib}/modelos.ts +0 -0
- /package/{kits/apple-tipografico/elementos → materiais/apple-tipografico/lib}/raymarch.ts +0 -0
- /package/{kits/apple-tipografico/assets → materiais/apple-tipografico}/sons/assinatura.mp3 +0 -0
- /package/{kits/apple-tipografico/assets → materiais/apple-tipografico}/sons/clique.mp3 +0 -0
- /package/{kits/apple-tipografico/assets → materiais/apple-tipografico}/sons/impacto.mp3 +0 -0
- /package/{kits/apple-tipografico/assets → materiais/apple-tipografico}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/apple-tipografico/assets → materiais/apple-tipografico}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/apple-tipografico/assets → materiais/apple-tipografico}/sons/subida.mp3 +0 -0
- /package/{kits/apple-tipografico/assets → materiais/apple-tipografico}/sons/swoosh.mp3 +0 -0
- /package/{kits/apple-tipografico/assets → materiais/apple-tipografico}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/apple-tipografico/assets → materiais/apple-tipografico}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/apple-tipografico/assets → materiais/apple-tipografico}/trilha/tech-claro-125bpm.mp3 +0 -0
- /package/{kits/aquarela/elementos → materiais/aquarela/camera}/Camera.tsx +0 -0
- /package/{kits/aquarela/assets → materiais/aquarela}/fontes/OFL-Caveat.txt +0 -0
- /package/{kits/aquarela/assets → materiais/aquarela}/fontes/OFL-Fraunces.txt +0 -0
- /package/{kits/aquarela/assets → materiais/aquarela}/fontes/caveat-latin.woff2 +0 -0
- /package/{kits/aquarela/assets → materiais/aquarela}/fontes/fraunces-latin.woff2 +0 -0
- /package/{kits/aquarela/assets → materiais/aquarela}/sons/assinatura.mp3 +0 -0
- /package/{kits/aquarela/assets → materiais/aquarela}/sons/gota.mp3 +0 -0
- /package/{kits/aquarela/assets → materiais/aquarela}/sons/impacto.mp3 +0 -0
- /package/{kits/aquarela/assets → materiais/aquarela}/sons/palavra.mp3 +0 -0
- /package/{kits/aquarela/assets → materiais/aquarela}/sons/papel-cai.mp3 +0 -0
- /package/{kits/aquarela/assets → materiais/aquarela}/sons/pop-mancha.mp3 +0 -0
- /package/{kits/aquarela/assets → materiais/aquarela}/sons/risco.mp3 +0 -0
- /package/{kits/aquarela/assets → materiais/aquarela}/sons/whoosh-pincel.mp3 +0 -0
- /package/{kits/aquarela/assets → materiais/aquarela}/trilha/calma-com-punch-108bpm.mp3 +0 -0
- /package/{kits/aurora/elementos → materiais/aurora/camera}/Camera.tsx +0 -0
- /package/{kits/aurora/assets → materiais/aurora}/fontes/OFL-InstrumentSerif.txt +0 -0
- /package/{kits/aurora/assets → materiais/aurora}/fontes/OFL-Manrope.txt +0 -0
- /package/{kits/aurora/assets → materiais/aurora}/fontes/instrument-latin.woff2 +0 -0
- /package/{kits/aurora/assets → materiais/aurora}/fontes/manrope-latin.woff2 +0 -0
- /package/{kits/aurora/assets → materiais/aurora}/sons/assinatura.mp3 +0 -0
- /package/{kits/aurora/assets → materiais/aurora}/sons/brilho.mp3 +0 -0
- /package/{kits/aurora/assets → materiais/aurora}/sons/meteoro.mp3 +0 -0
- /package/{kits/aurora/assets → materiais/aurora}/sons/onda.mp3 +0 -0
- /package/{kits/aurora/assets → materiais/aurora}/sons/sino.mp3 +0 -0
- /package/{kits/aurora/assets → materiais/aurora}/sons/sopro.mp3 +0 -0
- /package/{kits/aurora/assets → materiais/aurora}/sons/subida.mp3 +0 -0
- /package/{kits/aurora/assets → materiais/aurora}/sons/toque.mp3 +0 -0
- /package/{kits/aurora/assets → materiais/aurora}/trilha/suave-88bpm.mp3 +0 -0
- /package/{kits/bauhaus/assets → materiais/bauhaus}/fontes/OFL-bebas-neue.txt +0 -0
- /package/{kits/bauhaus/assets → materiais/bauhaus}/fontes/OFL-jost-900.txt +0 -0
- /package/{kits/bauhaus/assets → materiais/bauhaus}/fontes/bebas-neue.woff2 +0 -0
- /package/{kits/bauhaus/assets → materiais/bauhaus}/fontes/jost-900.woff2 +0 -0
- /package/{kits/bauhaus/assets → materiais/bauhaus}/sons/assinatura.mp3 +0 -0
- /package/{kits/bauhaus/assets → materiais/bauhaus}/sons/clique.mp3 +0 -0
- /package/{kits/bauhaus/assets → materiais/bauhaus}/sons/impacto.mp3 +0 -0
- /package/{kits/bauhaus/assets → materiais/bauhaus}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/bauhaus/assets → materiais/bauhaus}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/bauhaus/assets → materiais/bauhaus}/sons/subida.mp3 +0 -0
- /package/{kits/bauhaus/assets → materiais/bauhaus}/sons/swoosh.mp3 +0 -0
- /package/{kits/bauhaus/assets → materiais/bauhaus}/sons/tick.mp3 +0 -0
- /package/{kits/bauhaus/assets → materiais/bauhaus}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/bauhaus/assets → materiais/bauhaus}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/bauhaus/assets → materiais/bauhaus}/trilha/trilha.mp3 +0 -0
- /package/{kits/brutalista/elementos → materiais/brutalista/camera}/Camera.tsx +0 -0
- /package/{kits/brutalista/assets → materiais/brutalista}/fontes/OFL-ArchivoBlack.txt +0 -0
- /package/{kits/brutalista/assets → materiais/brutalista}/fontes/OFL-JetBrainsMono.txt +0 -0
- /package/{kits/brutalista/assets → materiais/brutalista}/fontes/archivo-black.woff2 +0 -0
- /package/{kits/brutalista/assets → materiais/brutalista}/fontes/jetbrains-mono.woff2 +0 -0
- /package/{kits/brutalista/assets → materiais/brutalista}/sons/assinatura.mp3 +0 -0
- /package/{kits/brutalista/assets → materiais/brutalista}/sons/clique.mp3 +0 -0
- /package/{kits/brutalista/assets → materiais/brutalista}/sons/impacto.mp3 +0 -0
- /package/{kits/brutalista/assets → materiais/brutalista}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/brutalista/assets → materiais/brutalista}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/brutalista/assets → materiais/brutalista}/sons/subida.mp3 +0 -0
- /package/{kits/brutalista/assets → materiais/brutalista}/sons/swoosh.mp3 +0 -0
- /package/{kits/brutalista/assets → materiais/brutalista}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/brutalista/assets → materiais/brutalista}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/brutalista/assets → materiais/brutalista}/trilha/bruta-108bpm.mp3 +0 -0
- /package/{kits/campos-de-cor/assets → materiais/campos-de-cor}/fontes/OFL-Archivo-Black.txt +0 -0
- /package/{kits/campos-de-cor/assets → materiais/campos-de-cor}/fontes/OFL-DM-Mono.txt +0 -0
- /package/{kits/campos-de-cor/assets → materiais/campos-de-cor}/fontes/OFL-Playfair-Italic.txt +0 -0
- /package/{kits/campos-de-cor/assets → materiais/campos-de-cor}/fontes/archivo-black.woff2 +0 -0
- /package/{kits/campos-de-cor/assets → materiais/campos-de-cor}/fontes/dm-mono.woff2 +0 -0
- /package/{kits/campos-de-cor/assets → materiais/campos-de-cor}/fontes/playfair-italic.woff2 +0 -0
- /package/{kits/campos-de-cor/assets → materiais/campos-de-cor}/sons/assinatura.mp3 +0 -0
- /package/{kits/campos-de-cor/assets → materiais/campos-de-cor}/sons/clique.mp3 +0 -0
- /package/{kits/campos-de-cor/assets → materiais/campos-de-cor}/sons/impacto.mp3 +0 -0
- /package/{kits/campos-de-cor/assets → materiais/campos-de-cor}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/campos-de-cor/assets → materiais/campos-de-cor}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/campos-de-cor/assets → materiais/campos-de-cor}/sons/subida.mp3 +0 -0
- /package/{kits/campos-de-cor/assets → materiais/campos-de-cor}/sons/swoosh.mp3 +0 -0
- /package/{kits/campos-de-cor/assets → materiais/campos-de-cor}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/campos-de-cor/assets → materiais/campos-de-cor}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/campos-de-cor/assets → materiais/campos-de-cor}/trilha/trilha.mp3 +0 -0
- /package/{kits/cartaz-cinetico/elementos → materiais/cartaz-cinetico/camera}/Camera.tsx +0 -0
- /package/{kits/cartaz-cinetico/assets → materiais/cartaz-cinetico}/fontes/OFL-Anton.txt +0 -0
- /package/{kits/cartaz-cinetico/assets → materiais/cartaz-cinetico}/fontes/OFL-Archivo.txt +0 -0
- /package/{kits/cartaz-cinetico/assets → materiais/cartaz-cinetico}/fontes/anton.woff2 +0 -0
- /package/{kits/cartaz-cinetico/assets → materiais/cartaz-cinetico}/fontes/archivo.woff2 +0 -0
- /package/{kits/cartaz-cinetico/assets → materiais/cartaz-cinetico}/sons/assinatura.mp3 +0 -0
- /package/{kits/cartaz-cinetico/assets → materiais/cartaz-cinetico}/sons/clique.mp3 +0 -0
- /package/{kits/cartaz-cinetico/assets → materiais/cartaz-cinetico}/sons/impacto.mp3 +0 -0
- /package/{kits/cartaz-cinetico/assets → materiais/cartaz-cinetico}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/cartaz-cinetico/assets → materiais/cartaz-cinetico}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/cartaz-cinetico/assets → materiais/cartaz-cinetico}/sons/subida.mp3 +0 -0
- /package/{kits/cartaz-cinetico/assets → materiais/cartaz-cinetico}/sons/swoosh.mp3 +0 -0
- /package/{kits/cartaz-cinetico/assets → materiais/cartaz-cinetico}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/cartaz-cinetico/assets → materiais/cartaz-cinetico}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/cartaz-cinetico/assets → materiais/cartaz-cinetico}/trilha/cartaz-124bpm.mp3 +0 -0
- /package/{kits/colagem/assets → materiais/colagem}/fontes/OFL-abril-fatface.txt +0 -0
- /package/{kits/colagem/assets → materiais/colagem}/fontes/OFL-special-elite.txt +0 -0
- /package/{kits/colagem/assets → materiais/colagem}/fontes/abril-fatface.woff2 +0 -0
- /package/{kits/colagem/assets → materiais/colagem}/fontes/special-elite.woff2 +0 -0
- /package/{kits/colagem/elementos → materiais/colagem/formas}/Overlay.tsx +0 -0
- /package/{kits/colagem/assets → materiais/colagem}/sons/assinatura.mp3 +0 -0
- /package/{kits/colagem/assets → materiais/colagem}/sons/clique.mp3 +0 -0
- /package/{kits/colagem/assets → materiais/colagem}/sons/impacto.mp3 +0 -0
- /package/{kits/colagem/assets → materiais/colagem}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/colagem/assets → materiais/colagem}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/colagem/assets → materiais/colagem}/sons/subida.mp3 +0 -0
- /package/{kits/colagem/assets → materiais/colagem}/sons/swoosh.mp3 +0 -0
- /package/{kits/colagem/assets → materiais/colagem}/sons/tick.mp3 +0 -0
- /package/{kits/colagem/assets → materiais/colagem}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/colagem/assets → materiais/colagem}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/colagem/assets → materiais/colagem}/trilha/trilha.mp3 +0 -0
- /package/{kits/contagem/elementos → materiais/contagem/camera}/Camera.tsx +0 -0
- /package/{kits/contagem/assets → materiais/contagem}/fontes/OFL-BigShouldersDisplay.txt +0 -0
- /package/{kits/contagem/assets → materiais/contagem}/fontes/OFL-SpaceMono.txt +0 -0
- /package/{kits/contagem/assets → materiais/contagem}/fontes/bigshoulders.woff2 +0 -0
- /package/{kits/contagem/assets → materiais/contagem}/fontes/spacemono.woff2 +0 -0
- /package/{kits/contagem/assets → materiais/contagem}/sons/assinatura.mp3 +0 -0
- /package/{kits/contagem/assets → materiais/contagem}/sons/clique.mp3 +0 -0
- /package/{kits/contagem/assets → materiais/contagem}/sons/confete.mp3 +0 -0
- /package/{kits/contagem/assets → materiais/contagem}/sons/impacto.mp3 +0 -0
- /package/{kits/contagem/assets → materiais/contagem}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/contagem/assets → materiais/contagem}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/contagem/assets → materiais/contagem}/sons/subida.mp3 +0 -0
- /package/{kits/contagem/assets → materiais/contagem}/sons/swoosh.mp3 +0 -0
- /package/{kits/contagem/assets → materiais/contagem}/sons/tick.mp3 +0 -0
- /package/{kits/contagem/assets → materiais/contagem}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/contagem/assets → materiais/contagem}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/contagem/assets → materiais/contagem}/trilha/pulso-128bpm.mp3 +0 -0
- /package/{kits/convite-evento/elementos → materiais/convite-evento/camera}/Camera.tsx +0 -0
- /package/{kits/convite-evento/assets → materiais/convite-evento}/fontes/OFL-InstrumentSerif.txt +0 -0
- /package/{kits/convite-evento/assets → materiais/convite-evento}/fontes/OFL-Unbounded.txt +0 -0
- /package/{kits/convite-evento/assets → materiais/convite-evento}/fontes/instrumentserif-i.woff2 +0 -0
- /package/{kits/convite-evento/assets → materiais/convite-evento}/fontes/unbounded.woff2 +0 -0
- /package/{kits/convite-evento/assets → materiais/convite-evento}/sons/assinatura.mp3 +0 -0
- /package/{kits/convite-evento/assets → materiais/convite-evento}/sons/clique.mp3 +0 -0
- /package/{kits/convite-evento/assets → materiais/convite-evento}/sons/confete.mp3 +0 -0
- /package/{kits/convite-evento/assets → materiais/convite-evento}/sons/impacto.mp3 +0 -0
- /package/{kits/convite-evento/assets → materiais/convite-evento}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/convite-evento/assets → materiais/convite-evento}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/convite-evento/assets → materiais/convite-evento}/sons/subida.mp3 +0 -0
- /package/{kits/convite-evento/assets → materiais/convite-evento}/sons/swoosh.mp3 +0 -0
- /package/{kits/convite-evento/assets → materiais/convite-evento}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/convite-evento/assets → materiais/convite-evento}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/convite-evento/assets → materiais/convite-evento}/trilha/festa-112bpm.mp3 +0 -0
- /package/{kits/corte-podcast/elementos → materiais/corte-podcast/camera}/Camera.tsx +0 -0
- /package/{kits/corte-podcast/assets → materiais/corte-podcast}/fontes/OFL-Anton.txt +0 -0
- /package/{kits/corte-podcast/assets → materiais/corte-podcast}/fontes/OFL-IBMPlexMono.txt +0 -0
- /package/{kits/corte-podcast/assets → materiais/corte-podcast}/fontes/anton.woff2 +0 -0
- /package/{kits/corte-podcast/assets → materiais/corte-podcast}/fontes/plexmono.woff2 +0 -0
- /package/{kits/corte-podcast/assets → materiais/corte-podcast}/sons/assinatura.mp3 +0 -0
- /package/{kits/corte-podcast/assets → materiais/corte-podcast}/sons/clique.mp3 +0 -0
- /package/{kits/corte-podcast/assets → materiais/corte-podcast}/sons/impacto.mp3 +0 -0
- /package/{kits/corte-podcast/assets → materiais/corte-podcast}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/corte-podcast/assets → materiais/corte-podcast}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/corte-podcast/assets → materiais/corte-podcast}/sons/subida.mp3 +0 -0
- /package/{kits/corte-podcast/assets → materiais/corte-podcast}/sons/swoosh.mp3 +0 -0
- /package/{kits/corte-podcast/assets → materiais/corte-podcast}/sons/tick.mp3 +0 -0
- /package/{kits/corte-podcast/assets → materiais/corte-podcast}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/corte-podcast/assets → materiais/corte-podcast}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/corte-podcast/assets → materiais/corte-podcast}/trilha/lofi-pulso-100bpm.mp3 +0 -0
- /package/{kits/cubos/elementos → materiais/cubos/camera}/Camera.tsx +0 -0
- /package/{kits/cubos/assets → materiais/cubos}/fontes/OFL-ArchivoBlack.txt +0 -0
- /package/{kits/cubos/assets → materiais/cubos}/fontes/OFL-DMSans.txt +0 -0
- /package/{kits/cubos/assets → materiais/cubos}/fontes/archivoblack-latin.woff2 +0 -0
- /package/{kits/cubos/assets → materiais/cubos}/fontes/dmsans-latin.woff2 +0 -0
- /package/{kits/cubos/assets → materiais/cubos}/sons/assinatura.mp3 +0 -0
- /package/{kits/cubos/assets → materiais/cubos}/sons/bloco.mp3 +0 -0
- /package/{kits/cubos/assets → materiais/cubos}/sons/desmonta.mp3 +0 -0
- /package/{kits/cubos/assets → materiais/cubos}/sons/encaixa.mp3 +0 -0
- /package/{kits/cubos/assets → materiais/cubos}/sons/estala.mp3 +0 -0
- /package/{kits/cubos/assets → materiais/cubos}/sons/gira.mp3 +0 -0
- /package/{kits/cubos/assets → materiais/cubos}/sons/queda.mp3 +0 -0
- /package/{kits/cubos/assets → materiais/cubos}/sons/whoosh.mp3 +0 -0
- /package/{kits/cubos/assets → materiais/cubos}/trilha/calma-com-punch-108bpm.mp3 +0 -0
- /package/{kits/dashboard-dados/assets → materiais/dashboard-dados}/fontes/OFL-IBM-Plex-Mono.txt +0 -0
- /package/{kits/dashboard-dados/assets → materiais/dashboard-dados}/fontes/OFL-Montserrat.txt +0 -0
- /package/{kits/dashboard-dados/assets → materiais/dashboard-dados}/fontes/montserrat.woff2 +0 -0
- /package/{kits/dashboard-dados/assets → materiais/dashboard-dados}/fontes/plex-mono.woff2 +0 -0
- /package/{kits/dashboard-dados/assets → materiais/dashboard-dados}/sons/assinatura.mp3 +0 -0
- /package/{kits/dashboard-dados/assets → materiais/dashboard-dados}/sons/clique.mp3 +0 -0
- /package/{kits/dashboard-dados/assets → materiais/dashboard-dados}/sons/impacto.mp3 +0 -0
- /package/{kits/dashboard-dados/assets → materiais/dashboard-dados}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/dashboard-dados/assets → materiais/dashboard-dados}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/dashboard-dados/assets → materiais/dashboard-dados}/sons/subida.mp3 +0 -0
- /package/{kits/dashboard-dados/assets → materiais/dashboard-dados}/sons/swoosh.mp3 +0 -0
- /package/{kits/dashboard-dados/assets → materiais/dashboard-dados}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/dashboard-dados/assets → materiais/dashboard-dados}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/dashboard-dados/assets → materiais/dashboard-dados}/trilha/trilha.mp3 +0 -0
- /package/{kits/depoimento/elementos → materiais/depoimento/camera}/Camera.tsx +0 -0
- /package/{kits/depoimento/assets → materiais/depoimento}/fontes/OFL-Newsreader.txt +0 -0
- /package/{kits/depoimento/assets → materiais/depoimento}/fontes/OFL-SpaceGrotesk.txt +0 -0
- /package/{kits/depoimento/assets → materiais/depoimento}/fontes/newsreader-i.woff2 +0 -0
- /package/{kits/depoimento/assets → materiais/depoimento}/fontes/spacegrotesk.woff2 +0 -0
- /package/{kits/depoimento/assets → materiais/depoimento}/sons/assinatura.mp3 +0 -0
- /package/{kits/depoimento/assets → materiais/depoimento}/sons/clique.mp3 +0 -0
- /package/{kits/depoimento/assets → materiais/depoimento}/sons/estrela.mp3 +0 -0
- /package/{kits/depoimento/assets → materiais/depoimento}/sons/impacto.mp3 +0 -0
- /package/{kits/depoimento/assets → materiais/depoimento}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/depoimento/assets → materiais/depoimento}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/depoimento/assets → materiais/depoimento}/sons/subida.mp3 +0 -0
- /package/{kits/depoimento/assets → materiais/depoimento}/sons/swoosh.mp3 +0 -0
- /package/{kits/depoimento/assets → materiais/depoimento}/sons/verificado.mp3 +0 -0
- /package/{kits/depoimento/assets → materiais/depoimento}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/depoimento/assets → materiais/depoimento}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/depoimento/assets → materiais/depoimento}/trilha/calor-104bpm.mp3 +0 -0
- /package/{kits/infografico/elementos → materiais/infografico/camera}/Camera.tsx +0 -0
- /package/{kits/infografico/assets → materiais/infografico}/fontes/OFL-Caveat.txt +0 -0
- /package/{kits/infografico/assets → materiais/infografico}/fontes/OFL-Outfit.txt +0 -0
- /package/{kits/infografico/assets → materiais/infografico}/fontes/caveat.woff2 +0 -0
- /package/{kits/infografico/assets → materiais/infografico}/fontes/outfit.woff2 +0 -0
- /package/{kits/infografico/assets → materiais/infografico}/sons/assinatura.mp3 +0 -0
- /package/{kits/infografico/assets → materiais/infografico}/sons/clique.mp3 +0 -0
- /package/{kits/infografico/assets → materiais/infografico}/sons/impacto.mp3 +0 -0
- /package/{kits/infografico/assets → materiais/infografico}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/infografico/assets → materiais/infografico}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/infografico/assets → materiais/infografico}/sons/subida.mp3 +0 -0
- /package/{kits/infografico/assets → materiais/infografico}/sons/swoosh.mp3 +0 -0
- /package/{kits/infografico/assets → materiais/infografico}/sons/traco.mp3 +0 -0
- /package/{kits/infografico/assets → materiais/infografico}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/infografico/assets → materiais/infografico}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/infografico/assets → materiais/infografico}/trilha/explica-100bpm.mp3 +0 -0
- /package/{kits/isometrico/assets → materiais/isometrico}/fontes/OFL-Archivo.txt +0 -0
- /package/{kits/isometrico/assets → materiais/isometrico}/fontes/OFL-Jost.txt +0 -0
- /package/{kits/isometrico/assets → materiais/isometrico}/fontes/archivo.woff2 +0 -0
- /package/{kits/isometrico/assets → materiais/isometrico}/fontes/jost.woff2 +0 -0
- /package/{kits/isometrico/elementos → materiais/isometrico/formas}/iso.tsx +0 -0
- /package/{kits/isometrico/assets → materiais/isometrico}/sons/assinatura.mp3 +0 -0
- /package/{kits/isometrico/assets → materiais/isometrico}/sons/clique.mp3 +0 -0
- /package/{kits/isometrico/assets → materiais/isometrico}/sons/impacto.mp3 +0 -0
- /package/{kits/isometrico/assets → materiais/isometrico}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/isometrico/assets → materiais/isometrico}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/isometrico/assets → materiais/isometrico}/sons/subida.mp3 +0 -0
- /package/{kits/isometrico/assets → materiais/isometrico}/sons/swoosh.mp3 +0 -0
- /package/{kits/isometrico/assets → materiais/isometrico}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/isometrico/assets → materiais/isometrico}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/isometrico/assets → materiais/isometrico}/trilha/trilha.mp3 +0 -0
- /package/{kits/jornal/elementos → materiais/jornal/camera}/Camera.tsx +0 -0
- /package/{kits/jornal/assets → materiais/jornal}/fontes/OFL-PlayfairDisplay.txt +0 -0
- /package/{kits/jornal/assets → materiais/jornal}/fontes/OFL-UnifrakturMaguntia.txt +0 -0
- /package/{kits/jornal/assets → materiais/jornal}/fontes/playfair-italic.woff2 +0 -0
- /package/{kits/jornal/assets → materiais/jornal}/fontes/playfair.woff2 +0 -0
- /package/{kits/jornal/assets → materiais/jornal}/fontes/unifraktur.woff2 +0 -0
- /package/{kits/jornal/assets → materiais/jornal}/sons/assinatura.mp3 +0 -0
- /package/{kits/jornal/assets → materiais/jornal}/sons/clique.mp3 +0 -0
- /package/{kits/jornal/assets → materiais/jornal}/sons/impacto.mp3 +0 -0
- /package/{kits/jornal/assets → materiais/jornal}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/jornal/assets → materiais/jornal}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/jornal/assets → materiais/jornal}/sons/subida.mp3 +0 -0
- /package/{kits/jornal/assets → materiais/jornal}/sons/swoosh.mp3 +0 -0
- /package/{kits/jornal/assets → materiais/jornal}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/jornal/assets → materiais/jornal}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/jornal/assets → materiais/jornal}/trilha/redacao-96bpm.mp3 +0 -0
- /package/{kits/legenda-viva/elementos → materiais/legenda-viva/camera}/Camera.tsx +0 -0
- /package/{kits/legenda-viva/assets → materiais/legenda-viva}/fontes/OFL-Inter.txt +0 -0
- /package/{kits/legenda-viva/assets → materiais/legenda-viva}/fontes/OFL-Montserrat.txt +0 -0
- /package/{kits/legenda-viva/assets → materiais/legenda-viva}/fontes/inter.woff2 +0 -0
- /package/{kits/legenda-viva/assets → materiais/legenda-viva}/fontes/montserrat.woff2 +0 -0
- /package/{kits/legenda-viva/assets → materiais/legenda-viva}/sons/assinatura.mp3 +0 -0
- /package/{kits/legenda-viva/assets → materiais/legenda-viva}/sons/clique.mp3 +0 -0
- /package/{kits/legenda-viva/assets → materiais/legenda-viva}/sons/impacto.mp3 +0 -0
- /package/{kits/legenda-viva/assets → materiais/legenda-viva}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/legenda-viva/assets → materiais/legenda-viva}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/legenda-viva/assets → materiais/legenda-viva}/sons/subida.mp3 +0 -0
- /package/{kits/legenda-viva/assets → materiais/legenda-viva}/sons/swoosh.mp3 +0 -0
- /package/{kits/legenda-viva/assets → materiais/legenda-viva}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/legenda-viva/assets → materiais/legenda-viva}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/legenda-viva/assets → materiais/legenda-viva}/trilha/voz-118bpm.mp3 +0 -0
- /package/{kits/luxo/elementos → materiais/luxo/camera}/Camera.tsx +0 -0
- /package/{kits/luxo/assets → materiais/luxo}/fontes/OFL-CormorantGaramond.txt +0 -0
- /package/{kits/luxo/assets → materiais/luxo}/fontes/OFL-Jost.txt +0 -0
- /package/{kits/luxo/assets → materiais/luxo}/fontes/cormorant-i.woff2 +0 -0
- /package/{kits/luxo/assets → materiais/luxo}/fontes/cormorant.woff2 +0 -0
- /package/{kits/luxo/assets → materiais/luxo}/fontes/jost.woff2 +0 -0
- /package/{kits/luxo/assets → materiais/luxo}/sons/assinatura.mp3 +0 -0
- /package/{kits/luxo/assets → materiais/luxo}/sons/clique.mp3 +0 -0
- /package/{kits/luxo/assets → materiais/luxo}/sons/impacto.mp3 +0 -0
- /package/{kits/luxo/assets → materiais/luxo}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/luxo/assets → materiais/luxo}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/luxo/assets → materiais/luxo}/sons/sino.mp3 +0 -0
- /package/{kits/luxo/assets → materiais/luxo}/sons/subida.mp3 +0 -0
- /package/{kits/luxo/assets → materiais/luxo}/sons/swoosh.mp3 +0 -0
- /package/{kits/luxo/assets → materiais/luxo}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/luxo/assets → materiais/luxo}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/luxo/assets → materiais/luxo}/trilha/ambar-78bpm.mp3 +0 -0
- /package/{kits/mapa/elementos → materiais/mapa/camera}/Camera.tsx +0 -0
- /package/{kits/mapa/assets → materiais/mapa}/fontes/OFL-DMMono.txt +0 -0
- /package/{kits/mapa/assets → materiais/mapa}/fontes/OFL-DMSans.txt +0 -0
- /package/{kits/mapa/assets → materiais/mapa}/fontes/dmmono.woff2 +0 -0
- /package/{kits/mapa/assets → materiais/mapa}/fontes/dmsans.woff2 +0 -0
- /package/{kits/mapa/assets → materiais/mapa}/sons/assinatura.mp3 +0 -0
- /package/{kits/mapa/assets → materiais/mapa}/sons/clique.mp3 +0 -0
- /package/{kits/mapa/assets → materiais/mapa}/sons/impacto.mp3 +0 -0
- /package/{kits/mapa/assets → materiais/mapa}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/mapa/assets → materiais/mapa}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/mapa/assets → materiais/mapa}/sons/quique.mp3 +0 -0
- /package/{kits/mapa/assets → materiais/mapa}/sons/subida.mp3 +0 -0
- /package/{kits/mapa/assets → materiais/mapa}/sons/swoosh.mp3 +0 -0
- /package/{kits/mapa/assets → materiais/mapa}/sons/traco.mp3 +0 -0
- /package/{kits/mapa/assets → materiais/mapa}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/mapa/assets → materiais/mapa}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/mapa/assets → materiais/mapa}/trilha/rota-100bpm.mp3 +0 -0
- /package/{kits/massinha/assets → materiais/massinha}/fontes/OFL-chewy.txt +0 -0
- /package/{kits/massinha/assets → materiais/massinha}/fontes/OFL-nunito-800.txt +0 -0
- /package/{kits/massinha/assets → materiais/massinha}/fontes/chewy.woff2 +0 -0
- /package/{kits/massinha/assets → materiais/massinha}/fontes/nunito-800.woff2 +0 -0
- /package/{kits/massinha/elementos → materiais/massinha/lib}/argila.ts +0 -0
- /package/{kits/massinha/assets → materiais/massinha}/sons/assinatura.mp3 +0 -0
- /package/{kits/massinha/assets → materiais/massinha}/sons/clique.mp3 +0 -0
- /package/{kits/massinha/assets → materiais/massinha}/sons/impacto.mp3 +0 -0
- /package/{kits/massinha/assets → materiais/massinha}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/massinha/assets → materiais/massinha}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/massinha/assets → materiais/massinha}/sons/subida.mp3 +0 -0
- /package/{kits/massinha/assets → materiais/massinha}/sons/swoosh.mp3 +0 -0
- /package/{kits/massinha/assets → materiais/massinha}/sons/tick.mp3 +0 -0
- /package/{kits/massinha/assets → materiais/massinha}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/massinha/assets → materiais/massinha}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/massinha/assets → materiais/massinha}/trilha/trilha.mp3 +0 -0
- /package/{kits/memphis/assets → materiais/memphis}/fontes/OFL-bowlby-one.txt +0 -0
- /package/{kits/memphis/assets → materiais/memphis}/fontes/OFL-dm-sans-800.txt +0 -0
- /package/{kits/memphis/assets → materiais/memphis}/fontes/bowlby-one.woff2 +0 -0
- /package/{kits/memphis/assets → materiais/memphis}/fontes/dm-sans-800.woff2 +0 -0
- /package/{kits/memphis/assets → materiais/memphis}/sons/assinatura.mp3 +0 -0
- /package/{kits/memphis/assets → materiais/memphis}/sons/clique.mp3 +0 -0
- /package/{kits/memphis/assets → materiais/memphis}/sons/impacto.mp3 +0 -0
- /package/{kits/memphis/assets → materiais/memphis}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/memphis/assets → materiais/memphis}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/memphis/assets → materiais/memphis}/sons/subida.mp3 +0 -0
- /package/{kits/memphis/assets → materiais/memphis}/sons/swoosh.mp3 +0 -0
- /package/{kits/memphis/assets → materiais/memphis}/sons/tick.mp3 +0 -0
- /package/{kits/memphis/assets → materiais/memphis}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/memphis/assets → materiais/memphis}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/memphis/assets → materiais/memphis}/trilha/trilha.mp3 +0 -0
- /package/{kits/metal-liquido/elementos → materiais/metal-liquido/camera}/Camera.tsx +0 -0
- /package/{kits/metal-liquido/assets → materiais/metal-liquido}/fontes/OFL-SpaceGrotesk.txt +0 -0
- /package/{kits/metal-liquido/assets → materiais/metal-liquido}/fontes/OFL-Unbounded.txt +0 -0
- /package/{kits/metal-liquido/assets → materiais/metal-liquido}/fontes/grotesk-latin.woff2 +0 -0
- /package/{kits/metal-liquido/assets → materiais/metal-liquido}/fontes/unbounded-latin.woff2 +0 -0
- /package/{kits/metal-liquido/assets → materiais/metal-liquido}/sons/assinatura.mp3 +0 -0
- /package/{kits/metal-liquido/assets → materiais/metal-liquido}/sons/clique.mp3 +0 -0
- /package/{kits/metal-liquido/assets → materiais/metal-liquido}/sons/cromo.mp3 +0 -0
- /package/{kits/metal-liquido/assets → materiais/metal-liquido}/sons/liquido.mp3 +0 -0
- /package/{kits/metal-liquido/assets → materiais/metal-liquido}/sons/quique.mp3 +0 -0
- /package/{kits/metal-liquido/assets → materiais/metal-liquido}/sons/subida.mp3 +0 -0
- /package/{kits/metal-liquido/assets → materiais/metal-liquido}/sons/varre.mp3 +0 -0
- /package/{kits/metal-liquido/assets → materiais/metal-liquido}/sons/whoosh.mp3 +0 -0
- /package/{kits/metal-liquido/assets → materiais/metal-liquido}/trilha/sombrio-114bpm.mp3 +0 -0
- /package/{kits/minimal/elementos → materiais/minimal/camera}/Camera.tsx +0 -0
- /package/{kits/minimal/assets → materiais/minimal}/fontes/OFL-HankenGrotesk.txt +0 -0
- /package/{kits/minimal/assets → materiais/minimal}/fontes/OFL-SplineSansMono.txt +0 -0
- /package/{kits/minimal/assets → materiais/minimal}/fontes/hanken.woff2 +0 -0
- /package/{kits/minimal/assets → materiais/minimal}/fontes/splinemono.woff2 +0 -0
- /package/{kits/minimal/assets → materiais/minimal}/sons/assinatura.mp3 +0 -0
- /package/{kits/minimal/assets → materiais/minimal}/sons/clique.mp3 +0 -0
- /package/{kits/minimal/assets → materiais/minimal}/sons/impacto.mp3 +0 -0
- /package/{kits/minimal/assets → materiais/minimal}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/minimal/assets → materiais/minimal}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/minimal/assets → materiais/minimal}/sons/subida.mp3 +0 -0
- /package/{kits/minimal/assets → materiais/minimal}/sons/swoosh.mp3 +0 -0
- /package/{kits/minimal/assets → materiais/minimal}/sons/toque.mp3 +0 -0
- /package/{kits/minimal/assets → materiais/minimal}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/minimal/assets → materiais/minimal}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/minimal/assets → materiais/minimal}/trilha/vazio-90bpm.mp3 +0 -0
- /package/{kits/neon-cidade/elementos → materiais/neon-cidade/camera}/Camera.tsx +0 -0
- /package/{kits/neon-cidade/assets → materiais/neon-cidade}/fontes/OFL-BarlowCondensed.txt +0 -0
- /package/{kits/neon-cidade/assets → materiais/neon-cidade}/fontes/OFL-TiltNeon.txt +0 -0
- /package/{kits/neon-cidade/assets → materiais/neon-cidade}/fontes/barlow-latin.woff2 +0 -0
- /package/{kits/neon-cidade/assets → materiais/neon-cidade}/fontes/tiltneon-latin.woff2 +0 -0
- /package/{kits/neon-cidade/assets → materiais/neon-cidade}/sons/assinatura.mp3 +0 -0
- /package/{kits/neon-cidade/assets → materiais/neon-cidade}/sons/balanca.mp3 +0 -0
- /package/{kits/neon-cidade/assets → materiais/neon-cidade}/sons/clique.mp3 +0 -0
- /package/{kits/neon-cidade/assets → materiais/neon-cidade}/sons/impacto.mp3 +0 -0
- /package/{kits/neon-cidade/assets → materiais/neon-cidade}/sons/liga.mp3 +0 -0
- /package/{kits/neon-cidade/assets → materiais/neon-cidade}/sons/tick.mp3 +0 -0
- /package/{kits/neon-cidade/assets → materiais/neon-cidade}/sons/whoosh.mp3 +0 -0
- /package/{kits/neon-cidade/assets → materiais/neon-cidade}/sons/zumbido.mp3 +0 -0
- /package/{kits/neon-cidade/assets → materiais/neon-cidade}/trilha/noite-100bpm.mp3 +0 -0
- /package/{kits/notion-editorial/assets → materiais/notion-editorial}/fontes/OFL-Cormorant-Italic.txt +0 -0
- /package/{kits/notion-editorial/assets → materiais/notion-editorial}/fontes/OFL-Cormorant.txt +0 -0
- /package/{kits/notion-editorial/assets → materiais/notion-editorial}/fontes/OFL-Jost.txt +0 -0
- /package/{kits/notion-editorial/assets → materiais/notion-editorial}/fontes/cormorant-italic.woff2 +0 -0
- /package/{kits/notion-editorial/assets → materiais/notion-editorial}/fontes/cormorant.woff2 +0 -0
- /package/{kits/notion-editorial/assets → materiais/notion-editorial}/fontes/jost.woff2 +0 -0
- /package/{kits/notion-editorial/elementos → materiais/notion-editorial/formas}/desenho.tsx +0 -0
- /package/{kits/notion-editorial/assets → materiais/notion-editorial}/sons/assinatura.mp3 +0 -0
- /package/{kits/notion-editorial/assets → materiais/notion-editorial}/sons/clique.mp3 +0 -0
- /package/{kits/notion-editorial/assets → materiais/notion-editorial}/sons/impacto.mp3 +0 -0
- /package/{kits/notion-editorial/assets → materiais/notion-editorial}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/notion-editorial/assets → materiais/notion-editorial}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/notion-editorial/assets → materiais/notion-editorial}/sons/subida.mp3 +0 -0
- /package/{kits/notion-editorial/assets → materiais/notion-editorial}/sons/swoosh.mp3 +0 -0
- /package/{kits/notion-editorial/assets → materiais/notion-editorial}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/notion-editorial/assets → materiais/notion-editorial}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/notion-editorial/assets → materiais/notion-editorial}/trilha/trilha.mp3 +0 -0
- /package/{kits/papel-recortado/assets → materiais/papel-recortado}/fontes/OFL-fredoka-700.txt +0 -0
- /package/{kits/papel-recortado/assets → materiais/papel-recortado}/fontes/OFL-nunito-700.txt +0 -0
- /package/{kits/papel-recortado/assets → materiais/papel-recortado}/fontes/fredoka-700.woff2 +0 -0
- /package/{kits/papel-recortado/assets → materiais/papel-recortado}/fontes/nunito-700.woff2 +0 -0
- /package/{kits/papel-recortado/elementos → materiais/papel-recortado/formas}/Filtros.tsx +0 -0
- /package/{kits/papel-recortado/assets → materiais/papel-recortado}/sons/assinatura.mp3 +0 -0
- /package/{kits/papel-recortado/assets → materiais/papel-recortado}/sons/clique.mp3 +0 -0
- /package/{kits/papel-recortado/assets → materiais/papel-recortado}/sons/impacto.mp3 +0 -0
- /package/{kits/papel-recortado/assets → materiais/papel-recortado}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/papel-recortado/assets → materiais/papel-recortado}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/papel-recortado/assets → materiais/papel-recortado}/sons/subida.mp3 +0 -0
- /package/{kits/papel-recortado/assets → materiais/papel-recortado}/sons/swoosh.mp3 +0 -0
- /package/{kits/papel-recortado/assets → materiais/papel-recortado}/sons/tick.mp3 +0 -0
- /package/{kits/papel-recortado/assets → materiais/papel-recortado}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/papel-recortado/assets → materiais/papel-recortado}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/papel-recortado/assets → materiais/papel-recortado}/trilha/trilha.mp3 +0 -0
- /package/{kits/pixel/assets → materiais/pixel}/fontes/OFL-pressstart2p.txt +0 -0
- /package/{kits/pixel/assets → materiais/pixel}/fontes/OFL-vt323.txt +0 -0
- /package/{kits/pixel/assets → materiais/pixel}/fontes/pressstart2p.woff2 +0 -0
- /package/{kits/pixel/assets → materiais/pixel}/fontes/vt323.woff2 +0 -0
- /package/{kits/pixel/assets → materiais/pixel}/sons/assinatura.mp3 +0 -0
- /package/{kits/pixel/assets → materiais/pixel}/sons/clique.mp3 +0 -0
- /package/{kits/pixel/assets → materiais/pixel}/sons/impacto.mp3 +0 -0
- /package/{kits/pixel/assets → materiais/pixel}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/pixel/assets → materiais/pixel}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/pixel/assets → materiais/pixel}/sons/subida.mp3 +0 -0
- /package/{kits/pixel/assets → materiais/pixel}/sons/swoosh.mp3 +0 -0
- /package/{kits/pixel/assets → materiais/pixel}/sons/tick.mp3 +0 -0
- /package/{kits/pixel/assets → materiais/pixel}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/pixel/assets → materiais/pixel}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/pixel/assets → materiais/pixel}/trilha/trilha.mp3 +0 -0
- /package/{kits/pontos-3d/elementos → materiais/pontos-3d/camera}/Camera.tsx +0 -0
- /package/{kits/pontos-3d/assets → materiais/pontos-3d}/fontes/OFL-JetBrainsMono.txt +0 -0
- /package/{kits/pontos-3d/assets → materiais/pontos-3d}/fontes/OFL-Sora.txt +0 -0
- /package/{kits/pontos-3d/assets → materiais/pontos-3d}/fontes/jetbrains-latin.woff2 +0 -0
- /package/{kits/pontos-3d/assets → materiais/pontos-3d}/fontes/sora-latin.woff2 +0 -0
- /package/{kits/pontos-3d/assets → materiais/pontos-3d}/sons/assinatura.mp3 +0 -0
- /package/{kits/pontos-3d/assets → materiais/pontos-3d}/sons/clique.mp3 +0 -0
- /package/{kits/pontos-3d/assets → materiais/pontos-3d}/sons/impacto.mp3 +0 -0
- /package/{kits/pontos-3d/assets → materiais/pontos-3d}/sons/pop.mp3 +0 -0
- /package/{kits/pontos-3d/assets → materiais/pontos-3d}/sons/subida.mp3 +0 -0
- /package/{kits/pontos-3d/assets → materiais/pontos-3d}/sons/tick.mp3 +0 -0
- /package/{kits/pontos-3d/assets → materiais/pontos-3d}/sons/varre.mp3 +0 -0
- /package/{kits/pontos-3d/assets → materiais/pontos-3d}/sons/whoosh.mp3 +0 -0
- /package/{kits/pontos-3d/assets → materiais/pontos-3d}/trilha/tech-120bpm.mp3 +0 -0
- /package/{kits/produto-3d/assets → materiais/produto-3d}/fontes/OFL-IBMPlexMono.txt +0 -0
- /package/{kits/produto-3d/assets → materiais/produto-3d}/fontes/OFL-Syncopate.txt +0 -0
- /package/{kits/produto-3d/assets → materiais/produto-3d}/fontes/plex-mono.woff2 +0 -0
- /package/{kits/produto-3d/assets → materiais/produto-3d}/fontes/syncopate-latin.woff2 +0 -0
- /package/{kits/produto-3d/elementos → materiais/produto-3d/lib}/modelos.ts +0 -0
- /package/{kits/produto-3d/elementos → materiais/produto-3d/lib}/raymarch.ts +0 -0
- /package/{kits/produto-3d/assets → materiais/produto-3d}/sons/assinatura.mp3 +0 -0
- /package/{kits/produto-3d/assets → materiais/produto-3d}/sons/clique.mp3 +0 -0
- /package/{kits/produto-3d/assets → materiais/produto-3d}/sons/impacto.mp3 +0 -0
- /package/{kits/produto-3d/assets → materiais/produto-3d}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/produto-3d/assets → materiais/produto-3d}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/produto-3d/assets → materiais/produto-3d}/sons/subida.mp3 +0 -0
- /package/{kits/produto-3d/assets → materiais/produto-3d}/sons/swoosh.mp3 +0 -0
- /package/{kits/produto-3d/assets → materiais/produto-3d}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/produto-3d/assets → materiais/produto-3d}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/produto-3d/assets → materiais/produto-3d}/trilha/trilha.mp3 +0 -0
- /package/{kits/quadro-giz/assets → materiais/quadro-giz}/fontes/OFL-patrick-hand.txt +0 -0
- /package/{kits/quadro-giz/assets → materiais/quadro-giz}/fontes/OFL-schoolbell.txt +0 -0
- /package/{kits/quadro-giz/assets → materiais/quadro-giz}/fontes/patrick-hand.woff2 +0 -0
- /package/{kits/quadro-giz/assets → materiais/quadro-giz}/fontes/schoolbell.woff2 +0 -0
- /package/{kits/quadro-giz/assets → materiais/quadro-giz}/sons/assinatura.mp3 +0 -0
- /package/{kits/quadro-giz/assets → materiais/quadro-giz}/sons/clique.mp3 +0 -0
- /package/{kits/quadro-giz/assets → materiais/quadro-giz}/sons/impacto.mp3 +0 -0
- /package/{kits/quadro-giz/assets → materiais/quadro-giz}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/quadro-giz/assets → materiais/quadro-giz}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/quadro-giz/assets → materiais/quadro-giz}/sons/subida.mp3 +0 -0
- /package/{kits/quadro-giz/assets → materiais/quadro-giz}/sons/swoosh.mp3 +0 -0
- /package/{kits/quadro-giz/assets → materiais/quadro-giz}/sons/tick.mp3 +0 -0
- /package/{kits/quadro-giz/assets → materiais/quadro-giz}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/quadro-giz/assets → materiais/quadro-giz}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/quadro-giz/assets → materiais/quadro-giz}/trilha/trilha.mp3 +0 -0
- /package/{kits/rabisco/assets → materiais/rabisco}/fontes/OFL-caveat-700.txt +0 -0
- /package/{kits/rabisco/assets → materiais/rabisco}/fontes/OFL-permanent-marker.txt +0 -0
- /package/{kits/rabisco/assets → materiais/rabisco}/fontes/caveat-700.woff2 +0 -0
- /package/{kits/rabisco/assets → materiais/rabisco}/fontes/permanent-marker.woff2 +0 -0
- /package/{kits/rabisco/elementos → materiais/rabisco/formas}/Overlay.tsx +0 -0
- /package/{kits/rabisco/assets → materiais/rabisco}/sons/assinatura.mp3 +0 -0
- /package/{kits/rabisco/assets → materiais/rabisco}/sons/clique.mp3 +0 -0
- /package/{kits/rabisco/assets → materiais/rabisco}/sons/impacto.mp3 +0 -0
- /package/{kits/rabisco/assets → materiais/rabisco}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/rabisco/assets → materiais/rabisco}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/rabisco/assets → materiais/rabisco}/sons/subida.mp3 +0 -0
- /package/{kits/rabisco/assets → materiais/rabisco}/sons/swoosh.mp3 +0 -0
- /package/{kits/rabisco/assets → materiais/rabisco}/sons/tick.mp3 +0 -0
- /package/{kits/rabisco/assets → materiais/rabisco}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/rabisco/assets → materiais/rabisco}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/rabisco/assets → materiais/rabisco}/trilha/trilha.mp3 +0 -0
- /package/{kits/retro-70/elementos → materiais/retro-70/camera}/Camera.tsx +0 -0
- /package/{kits/retro-70/assets → materiais/retro-70}/fontes/OFL-Fredoka.txt +0 -0
- /package/{kits/retro-70/assets → materiais/retro-70}/fontes/OFL-Shrikhand.txt +0 -0
- /package/{kits/retro-70/assets → materiais/retro-70}/fontes/fredoka.woff2 +0 -0
- /package/{kits/retro-70/assets → materiais/retro-70}/fontes/shrikhand.woff2 +0 -0
- /package/{kits/retro-70/assets → materiais/retro-70}/sons/assinatura.mp3 +0 -0
- /package/{kits/retro-70/assets → materiais/retro-70}/sons/clique.mp3 +0 -0
- /package/{kits/retro-70/assets → materiais/retro-70}/sons/impacto.mp3 +0 -0
- /package/{kits/retro-70/assets → materiais/retro-70}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/retro-70/assets → materiais/retro-70}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/retro-70/assets → materiais/retro-70}/sons/subida.mp3 +0 -0
- /package/{kits/retro-70/assets → materiais/retro-70}/sons/swoosh.mp3 +0 -0
- /package/{kits/retro-70/assets → materiais/retro-70}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/retro-70/assets → materiais/retro-70}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/retro-70/assets → materiais/retro-70}/trilha/solar-104bpm.mp3 +0 -0
- /package/{kits/revista/elementos → materiais/revista/camera}/Camera.tsx +0 -0
- /package/{kits/revista/assets → materiais/revista}/fontes/OFL-CormorantGaramond.txt +0 -0
- /package/{kits/revista/assets → materiais/revista}/fontes/OFL-Jost.txt +0 -0
- /package/{kits/revista/assets → materiais/revista}/fontes/cormorant-italic.woff2 +0 -0
- /package/{kits/revista/assets → materiais/revista}/fontes/cormorant.woff2 +0 -0
- /package/{kits/revista/assets → materiais/revista}/fontes/jost.woff2 +0 -0
- /package/{kits/revista/assets → materiais/revista}/sons/assinatura.mp3 +0 -0
- /package/{kits/revista/assets → materiais/revista}/sons/clique.mp3 +0 -0
- /package/{kits/revista/assets → materiais/revista}/sons/impacto.mp3 +0 -0
- /package/{kits/revista/assets → materiais/revista}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/revista/assets → materiais/revista}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/revista/assets → materiais/revista}/sons/subida.mp3 +0 -0
- /package/{kits/revista/assets → materiais/revista}/sons/swoosh.mp3 +0 -0
- /package/{kits/revista/assets → materiais/revista}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/revista/assets → materiais/revista}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/revista/assets → materiais/revista}/trilha/editorial-100bpm.mp3 +0 -0
- /package/{kits/risografia/assets → materiais/risografia}/fontes/OFL-bricolage-800.txt +0 -0
- /package/{kits/risografia/assets → materiais/risografia}/fontes/OFL-space-mono-700.txt +0 -0
- /package/{kits/risografia/assets → materiais/risografia}/fontes/bricolage-800.woff2 +0 -0
- /package/{kits/risografia/assets → materiais/risografia}/fontes/space-mono-700.woff2 +0 -0
- /package/{kits/risografia/assets → materiais/risografia}/sons/assinatura.mp3 +0 -0
- /package/{kits/risografia/assets → materiais/risografia}/sons/clique.mp3 +0 -0
- /package/{kits/risografia/assets → materiais/risografia}/sons/impacto.mp3 +0 -0
- /package/{kits/risografia/assets → materiais/risografia}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/risografia/assets → materiais/risografia}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/risografia/assets → materiais/risografia}/sons/subida.mp3 +0 -0
- /package/{kits/risografia/assets → materiais/risografia}/sons/swoosh.mp3 +0 -0
- /package/{kits/risografia/assets → materiais/risografia}/sons/tick.mp3 +0 -0
- /package/{kits/risografia/assets → materiais/risografia}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/risografia/assets → materiais/risografia}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/risografia/assets → materiais/risografia}/trilha/trilha.mp3 +0 -0
- /package/materiais/saas-linear/{paleta.json → cores/paleta.json} +0 -0
- /package/{kits/saas-linear/assets → materiais/saas-linear}/trilha/trilha.mp3 +0 -0
- /package/{kits/stripe-ondas/assets → materiais/stripe-ondas}/fontes/OFL-DM-Mono.txt +0 -0
- /package/{kits/stripe-ondas/assets → materiais/stripe-ondas}/fontes/OFL-Inter.txt +0 -0
- /package/{kits/stripe-ondas/assets → materiais/stripe-ondas}/fontes/dm-mono.woff2 +0 -0
- /package/{kits/stripe-ondas/assets → materiais/stripe-ondas}/fontes/inter.woff2 +0 -0
- /package/{kits/stripe-ondas/assets → materiais/stripe-ondas}/sons/assinatura.mp3 +0 -0
- /package/{kits/stripe-ondas/assets → materiais/stripe-ondas}/sons/clique.mp3 +0 -0
- /package/{kits/stripe-ondas/assets → materiais/stripe-ondas}/sons/impacto.mp3 +0 -0
- /package/{kits/stripe-ondas/assets → materiais/stripe-ondas}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/stripe-ondas/assets → materiais/stripe-ondas}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/stripe-ondas/assets → materiais/stripe-ondas}/sons/subida.mp3 +0 -0
- /package/{kits/stripe-ondas/assets → materiais/stripe-ondas}/sons/swoosh.mp3 +0 -0
- /package/{kits/stripe-ondas/assets → materiais/stripe-ondas}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/stripe-ondas/assets → materiais/stripe-ondas}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/stripe-ondas/assets → materiais/stripe-ondas}/trilha/trilha.mp3 +0 -0
- /package/{kits/suica/elementos → materiais/suica/camera}/Camera.tsx +0 -0
- /package/{kits/suica/assets → materiais/suica}/fontes/OFL-IBMPlexMono.txt +0 -0
- /package/{kits/suica/assets → materiais/suica}/fontes/OFL-InterTight.txt +0 -0
- /package/{kits/suica/assets → materiais/suica}/fontes/inter-tight.woff2 +0 -0
- /package/{kits/suica/assets → materiais/suica}/fontes/plex-mono.woff2 +0 -0
- /package/{kits/saas-linear/assets → materiais/suica}/sons/assinatura.mp3 +0 -0
- /package/{kits/saas-linear/assets → materiais/suica}/sons/clique.mp3 +0 -0
- /package/{kits/saas-linear/assets → materiais/suica}/sons/impacto.mp3 +0 -0
- /package/{kits/saas-linear/assets → materiais/suica}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/saas-linear/assets → materiais/suica}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/saas-linear/assets → materiais/suica}/sons/subida.mp3 +0 -0
- /package/{kits/saas-linear/assets → materiais/suica}/sons/swoosh.mp3 +0 -0
- /package/{kits/saas-linear/assets → materiais/suica}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/saas-linear/assets → materiais/suica}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/suica/assets → materiais/suica}/trilha/frio-120bpm.mp3 +0 -0
- /package/{kits/synthwave/elementos → materiais/synthwave/camera}/Camera.tsx +0 -0
- /package/{kits/synthwave/assets → materiais/synthwave}/fontes/OFL-Orbitron.txt +0 -0
- /package/{kits/synthwave/assets → materiais/synthwave}/fontes/OFL-Rajdhani.txt +0 -0
- /package/{kits/synthwave/assets → materiais/synthwave}/fontes/orbitron.woff2 +0 -0
- /package/{kits/synthwave/assets → materiais/synthwave}/fontes/rajdhani.woff2 +0 -0
- /package/{kits/suica/assets → materiais/synthwave}/sons/assinatura.mp3 +0 -0
- /package/{kits/suica/assets → materiais/synthwave}/sons/clique.mp3 +0 -0
- /package/{kits/suica/assets → materiais/synthwave}/sons/impacto.mp3 +0 -0
- /package/{kits/suica/assets → materiais/synthwave}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/suica/assets → materiais/synthwave}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/suica/assets → materiais/synthwave}/sons/subida.mp3 +0 -0
- /package/{kits/suica/assets → materiais/synthwave}/sons/swoosh.mp3 +0 -0
- /package/{kits/suica/assets → materiais/synthwave}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/suica/assets → materiais/synthwave}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/synthwave/assets → materiais/synthwave}/trilha/noite-110bpm.mp3 +0 -0
- /package/{kits/terminal/assets → materiais/terminal}/fontes/OFL-jetbrains-mono-700.txt +0 -0
- /package/{kits/terminal/assets → materiais/terminal}/fontes/OFL-vt323.txt +0 -0
- /package/{kits/terminal/assets → materiais/terminal}/fontes/jetbrains-mono-700.woff2 +0 -0
- /package/{kits/terminal/assets → materiais/terminal}/fontes/vt323.woff2 +0 -0
- /package/{kits/terminal/assets → materiais/terminal}/sons/assinatura.mp3 +0 -0
- /package/{kits/terminal/assets → materiais/terminal}/sons/clique.mp3 +0 -0
- /package/{kits/terminal/assets → materiais/terminal}/sons/digitar.mp3 +0 -0
- /package/{kits/terminal/assets → materiais/terminal}/sons/impacto.mp3 +0 -0
- /package/{kits/terminal/assets → materiais/terminal}/sons/liga-crt.mp3 +0 -0
- /package/{kits/terminal/assets → materiais/terminal}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/terminal/assets → materiais/terminal}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/terminal/assets → materiais/terminal}/sons/subida.mp3 +0 -0
- /package/{kits/terminal/assets → materiais/terminal}/sons/swoosh.mp3 +0 -0
- /package/{kits/terminal/assets → materiais/terminal}/sons/tick.mp3 +0 -0
- /package/{kits/terminal/assets → materiais/terminal}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/terminal/assets → materiais/terminal}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/terminal/assets → materiais/terminal}/trilha/trilha.mp3 +0 -0
- /package/{kits/tiktok-energia/elementos → materiais/tiktok-energia/camera}/Camera.tsx +0 -0
- /package/{kits/tiktok-energia/assets → materiais/tiktok-energia}/fontes/OFL-Anton.txt +0 -0
- /package/{kits/tiktok-energia/assets → materiais/tiktok-energia}/fontes/OFL-Rubik.txt +0 -0
- /package/{kits/tiktok-energia/assets → materiais/tiktok-energia}/fontes/anton-latin.woff2 +0 -0
- /package/{kits/tiktok-energia/assets → materiais/tiktok-energia}/fontes/rubik-latin.woff2 +0 -0
- /package/{kits/tiktok-energia/assets → materiais/tiktok-energia}/sons/assinatura.mp3 +0 -0
- /package/{kits/tiktok-energia/assets → materiais/tiktok-energia}/sons/corte.mp3 +0 -0
- /package/{kits/tiktok-energia/assets → materiais/tiktok-energia}/sons/palavra.mp3 +0 -0
- /package/{kits/tiktok-energia/assets → materiais/tiktok-energia}/sons/pop.mp3 +0 -0
- /package/{kits/tiktok-energia/assets → materiais/tiktok-energia}/sons/soco.mp3 +0 -0
- /package/{kits/tiktok-energia/assets → materiais/tiktok-energia}/sons/subida.mp3 +0 -0
- /package/{kits/tiktok-energia/assets → materiais/tiktok-energia}/sons/whoosh.mp3 +0 -0
- /package/{kits/tiktok-energia/assets → materiais/tiktok-energia}/sons/zap.mp3 +0 -0
- /package/{kits/tiktok-energia/assets → materiais/tiktok-energia}/trilha/tech-128bpm.mp3 +0 -0
- /package/{kits/tunel/elementos → materiais/tunel/camera}/Camera.tsx +0 -0
- /package/{kits/tunel/assets → materiais/tunel}/fontes/OFL-ChakraPetch.txt +0 -0
- /package/{kits/tunel/assets → materiais/tunel}/fontes/OFL-Syncopate.txt +0 -0
- /package/{kits/tunel/assets → materiais/tunel}/fontes/chakra-latin.woff2 +0 -0
- /package/{kits/tunel/assets → materiais/tunel}/fontes/syncopate-latin.woff2 +0 -0
- /package/{kits/tunel/assets → materiais/tunel}/sons/assinatura.mp3 +0 -0
- /package/{kits/tunel/assets → materiais/tunel}/sons/clique.mp3 +0 -0
- /package/{kits/tunel/assets → materiais/tunel}/sons/impacto.mp3 +0 -0
- /package/{kits/tunel/assets → materiais/tunel}/sons/passa.mp3 +0 -0
- /package/{kits/tunel/assets → materiais/tunel}/sons/subida.mp3 +0 -0
- /package/{kits/tunel/assets → materiais/tunel}/sons/tick.mp3 +0 -0
- /package/{kits/tunel/assets → materiais/tunel}/sons/varre.mp3 +0 -0
- /package/{kits/tunel/assets → materiais/tunel}/sons/whoosh.mp3 +0 -0
- /package/{kits/tunel/assets → materiais/tunel}/trilha/tech-128bpm.mp3 +0 -0
- /package/{kits/tutorial-tela/assets → materiais/tutorial-tela}/fontes/OFL-JetBrainsMono.txt +0 -0
- /package/{kits/tutorial-tela/assets → materiais/tutorial-tela}/fontes/OFL-PlusJakartaSans.txt +0 -0
- /package/{kits/tutorial-tela/assets → materiais/tutorial-tela}/fontes/jakarta.woff2 +0 -0
- /package/{kits/tutorial-tela/assets → materiais/tutorial-tela}/fontes/jbmono.woff2 +0 -0
- /package/{kits/tutorial-tela/assets → materiais/tutorial-tela}/sons/assinatura.mp3 +0 -0
- /package/{kits/tutorial-tela/assets → materiais/tutorial-tela}/sons/clique.mp3 +0 -0
- /package/{kits/tutorial-tela/assets → materiais/tutorial-tela}/sons/digitar.mp3 +0 -0
- /package/{kits/tutorial-tela/assets → materiais/tutorial-tela}/sons/impacto.mp3 +0 -0
- /package/{kits/tutorial-tela/assets → materiais/tutorial-tela}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/tutorial-tela/assets → materiais/tutorial-tela}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/tutorial-tela/assets → materiais/tutorial-tela}/sons/subida.mp3 +0 -0
- /package/{kits/tutorial-tela/assets → materiais/tutorial-tela}/sons/sucesso.mp3 +0 -0
- /package/{kits/tutorial-tela/assets → materiais/tutorial-tela}/sons/swoosh.mp3 +0 -0
- /package/{kits/tutorial-tela/assets → materiais/tutorial-tela}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/tutorial-tela/assets → materiais/tutorial-tela}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/tutorial-tela/assets → materiais/tutorial-tela}/trilha/passo-108bpm.mp3 +0 -0
- /package/{kits/ugc-reels/elementos → materiais/ugc-reels/camera}/Camera.tsx +0 -0
- /package/{kits/ugc-reels/assets → materiais/ugc-reels}/fontes/OFL-Caveat.txt +0 -0
- /package/{kits/ugc-reels/assets → materiais/ugc-reels}/fontes/OFL-Montserrat.txt +0 -0
- /package/{kits/ugc-reels/assets → materiais/ugc-reels}/fontes/caveat-latin.woff2 +0 -0
- /package/{kits/ugc-reels/assets → materiais/ugc-reels}/fontes/montserrat-latin.woff2 +0 -0
- /package/{kits/ugc-reels/assets → materiais/ugc-reels}/sons/assinatura.mp3 +0 -0
- /package/{kits/ugc-reels/assets → materiais/ugc-reels}/sons/corte.mp3 +0 -0
- /package/{kits/ugc-reels/assets → materiais/ugc-reels}/sons/impacto.mp3 +0 -0
- /package/{kits/ugc-reels/assets → materiais/ugc-reels}/sons/notificacao.mp3 +0 -0
- /package/{kits/ugc-reels/assets → materiais/ugc-reels}/sons/palavra.mp3 +0 -0
- /package/{kits/ugc-reels/assets → materiais/ugc-reels}/sons/pop.mp3 +0 -0
- /package/{kits/ugc-reels/assets → materiais/ugc-reels}/sons/toque.mp3 +0 -0
- /package/{kits/ugc-reels/assets → materiais/ugc-reels}/sons/whoosh.mp3 +0 -0
- /package/{kits/ugc-reels/assets → materiais/ugc-reels}/trilha/pop-120bpm.mp3 +0 -0
- /package/{kits/vercel-mono/assets → materiais/vercel-mono}/fontes/OFL-Inter.txt +0 -0
- /package/{kits/vercel-mono/assets → materiais/vercel-mono}/fontes/OFL-JetBrains-Mono.txt +0 -0
- /package/{kits/vercel-mono/assets → materiais/vercel-mono}/fontes/inter.woff2 +0 -0
- /package/{kits/vercel-mono/assets → materiais/vercel-mono}/fontes/jetbrains-mono.woff2 +0 -0
- /package/{kits/synthwave/assets → materiais/vercel-mono}/sons/assinatura.mp3 +0 -0
- /package/{kits/synthwave/assets → materiais/vercel-mono}/sons/clique.mp3 +0 -0
- /package/{kits/synthwave/assets → materiais/vercel-mono}/sons/impacto.mp3 +0 -0
- /package/{kits/synthwave/assets → materiais/vercel-mono}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/synthwave/assets → materiais/vercel-mono}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/synthwave/assets → materiais/vercel-mono}/sons/subida.mp3 +0 -0
- /package/{kits/synthwave/assets → materiais/vercel-mono}/sons/swoosh.mp3 +0 -0
- /package/{kits/synthwave/assets → materiais/vercel-mono}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/synthwave/assets → materiais/vercel-mono}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/vercel-mono/assets → materiais/vercel-mono}/trilha/trilha.mp3 +0 -0
- /package/{kits/vhs-90/elementos → materiais/vhs-90/camera}/Camera.tsx +0 -0
- /package/{kits/vhs-90/assets → materiais/vhs-90}/fontes/OFL-BebasNeue.txt +0 -0
- /package/{kits/vhs-90/assets → materiais/vhs-90}/fontes/OFL-VT323.txt +0 -0
- /package/{kits/vhs-90/assets → materiais/vhs-90}/fontes/bebas.woff2 +0 -0
- /package/{kits/vhs-90/assets → materiais/vhs-90}/fontes/vt323.woff2 +0 -0
- /package/{kits/vhs-90/assets → materiais/vhs-90}/sons/assinatura.mp3 +0 -0
- /package/{kits/vhs-90/assets → materiais/vhs-90}/sons/clique.mp3 +0 -0
- /package/{kits/vhs-90/assets → materiais/vhs-90}/sons/impacto.mp3 +0 -0
- /package/{kits/vhs-90/assets → materiais/vhs-90}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/vhs-90/assets → materiais/vhs-90}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/vhs-90/assets → materiais/vhs-90}/sons/subida.mp3 +0 -0
- /package/{kits/vhs-90/assets → materiais/vhs-90}/sons/swoosh.mp3 +0 -0
- /package/{kits/vhs-90/assets → materiais/vhs-90}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/vhs-90/assets → materiais/vhs-90}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/vhs-90/assets → materiais/vhs-90}/trilha/fita-88bpm.mp3 +0 -0
- /package/{kits/vidro-ios/assets → materiais/vidro-ios}/fontes/OFL-DM-Mono.txt +0 -0
- /package/{kits/vidro-ios/assets → materiais/vidro-ios}/fontes/OFL-Inter.txt +0 -0
- /package/{kits/vidro-ios/assets → materiais/vidro-ios}/fontes/dm-mono.woff2 +0 -0
- /package/{kits/vidro-ios/assets → materiais/vidro-ios}/fontes/inter.woff2 +0 -0
- /package/{kits/vidro-ios/assets → materiais/vidro-ios}/sons/assinatura.mp3 +0 -0
- /package/{kits/vidro-ios/assets → materiais/vidro-ios}/sons/clique.mp3 +0 -0
- /package/{kits/vidro-ios/assets → materiais/vidro-ios}/sons/impacto.mp3 +0 -0
- /package/{kits/vidro-ios/assets → materiais/vidro-ios}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/vidro-ios/assets → materiais/vidro-ios}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/vidro-ios/assets → materiais/vidro-ios}/sons/subida.mp3 +0 -0
- /package/{kits/vidro-ios/assets → materiais/vidro-ios}/sons/swoosh.mp3 +0 -0
- /package/{kits/vidro-ios/assets → materiais/vidro-ios}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/vidro-ios/assets → materiais/vidro-ios}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/vidro-ios/assets → materiais/vidro-ios}/trilha/trilha.mp3 +0 -0
- /package/{kits/y2k-cromado/elementos → materiais/y2k-cromado/camera}/Camera.tsx +0 -0
- /package/{kits/y2k-cromado/assets → materiais/y2k-cromado}/fontes/OFL-DMMono.txt +0 -0
- /package/{kits/y2k-cromado/assets → materiais/y2k-cromado}/fontes/OFL-Unbounded.txt +0 -0
- /package/{kits/y2k-cromado/assets → materiais/y2k-cromado}/fontes/dm-mono.woff2 +0 -0
- /package/{kits/y2k-cromado/assets → materiais/y2k-cromado}/fontes/unbounded.woff2 +0 -0
- /package/{kits/y2k-cromado/assets → materiais/y2k-cromado}/sons/assinatura.mp3 +0 -0
- /package/{kits/y2k-cromado/assets → materiais/y2k-cromado}/sons/clique.mp3 +0 -0
- /package/{kits/y2k-cromado/assets → materiais/y2k-cromado}/sons/impacto.mp3 +0 -0
- /package/{kits/y2k-cromado/assets → materiais/y2k-cromado}/sons/pop-cartao.mp3 +0 -0
- /package/{kits/y2k-cromado/assets → materiais/y2k-cromado}/sons/pop-palavra.mp3 +0 -0
- /package/{kits/y2k-cromado/assets → materiais/y2k-cromado}/sons/subida.mp3 +0 -0
- /package/{kits/y2k-cromado/assets → materiais/y2k-cromado}/sons/swoosh.mp3 +0 -0
- /package/{kits/y2k-cromado/assets → materiais/y2k-cromado}/sons/whoosh-entra.mp3 +0 -0
- /package/{kits/y2k-cromado/assets → materiais/y2k-cromado}/sons/whoosh-sai.mp3 +0 -0
- /package/{kits/y2k-cromado/assets → materiais/y2k-cromado}/trilha/y2k-128bpm.mp3 +0 -0
|
@@ -0,0 +1,4152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PrimoCode CLI
|
|
3
|
+
* Modos: primocode (agente completo, PADRÃO) · chat (conversa pura)
|
|
4
|
+
* Cada sessão trabalha dentro de uma pasta de projeto em ~/primocode/.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const readline = require('readline');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const os = require('os');
|
|
13
|
+
|
|
14
|
+
const pkg = require('../../package.json');
|
|
15
|
+
const ui = require('../tui/ui');
|
|
16
|
+
const entrada = require('../tui/entrada');
|
|
17
|
+
const { c, welcomeBox, Spinner } = ui;
|
|
18
|
+
const { escolherModo } = require('../modo.js');
|
|
19
|
+
const api = require('../provider/api');
|
|
20
|
+
const tools = require('../tool/tools');
|
|
21
|
+
const cfg = require('../config/config');
|
|
22
|
+
const nomeProjeto = require('../nome-projeto');
|
|
23
|
+
const { nomeCurto } = require('../nome-curto');
|
|
24
|
+
const provedorLocal = require('../provider/local/provedor');
|
|
25
|
+
const { runAct, interromper, ehTetoDeToken, ehTransitorio, esperaDoErro, mandarDuranteATarefa, sobrasDaCaixa } = require('../session/runner/act');
|
|
26
|
+
const fala = require('../fala');
|
|
27
|
+
const boasVindas = require('./boas-vindas');
|
|
28
|
+
const pasta = require('../pasta');
|
|
29
|
+
const outraPasta = require('../outra-pasta');
|
|
30
|
+
const agentsMd = require('../agents-md');
|
|
31
|
+
const catalogo = require('../skill/catalogo');
|
|
32
|
+
const effort = require('../effort');
|
|
33
|
+
const memoria = require('../session/memoria-conversa');
|
|
34
|
+
const registro = require('../registro');
|
|
35
|
+
const permissao = require('../permission/permissao');
|
|
36
|
+
const perigo = require('../permission/perigo');
|
|
37
|
+
const skills = require('../skill/skills');
|
|
38
|
+
const checkpoint = require('../session/checkpoint');
|
|
39
|
+
const comandosLib = require('./comandos');
|
|
40
|
+
const nomes = require('../nomes');
|
|
41
|
+
const marketplace = require('../skill/marketplace');
|
|
42
|
+
const portaoSkill = require('../skill/portao-skill');
|
|
43
|
+
const vozModo = require('../plugin/voz');
|
|
44
|
+
const conta = require('../config/conta');
|
|
45
|
+
const planosTela = require('../planos.js');
|
|
46
|
+
const nuvem = require('../nuvem');
|
|
47
|
+
const retomar = require('../session/retomar');
|
|
48
|
+
const compat = require('../compatibilidade');
|
|
49
|
+
const mencoesLib = require('../mencoes');
|
|
50
|
+
const extra = require('./comandos-extra');
|
|
51
|
+
const offline = require('../offline');
|
|
52
|
+
const conferirLib = require('../conferir');
|
|
53
|
+
|
|
54
|
+
/* O /custo: toda conversa com o modelo passa pelo lib/provider/api.js, e o contador
|
|
55
|
+
embrulha as funções dele uma vez, aqui. Quem atende é o provedor do /api
|
|
56
|
+
quando há um, senão o servidor — é por eles que o /usage separa. */
|
|
57
|
+
const contadorDaSessao = extra.novoContador();
|
|
58
|
+
extra.instalarContador(api, contadorDaSessao, () => {
|
|
59
|
+
const p = provedorLocal.atual();
|
|
60
|
+
return p ? p.nome : 'Servidor PrimoCode';
|
|
61
|
+
});
|
|
62
|
+
const tempos = require('../tempos');
|
|
63
|
+
|
|
64
|
+
// Rede de segurança de último recurso: sem isto, uma exceção fora de um
|
|
65
|
+
// try/catch (ex.: dentro de um callback de socket, como o parser de SSE) não
|
|
66
|
+
// era pega por ninguém e derrubava o processo INTEIRO em silêncio — o usuário
|
|
67
|
+
// via a resposta parar no meio e cair de volta pro shell, sem mensagem
|
|
68
|
+
// nenhuma. Agora vira um erro visível, e o processo continua de pé.
|
|
69
|
+
process.on('uncaughtException', (e) => {
|
|
70
|
+
fala.problema(e);
|
|
71
|
+
});
|
|
72
|
+
/* O Node sai com 0 quando o laço de eventos esvazia — e uma promessa que
|
|
73
|
+
nunca resolve, sem timer nem socket vivo, faz exatamente isso: o pedido
|
|
74
|
+
"termina" calado no meio (visto no vídeo de escopo fechado, 01/10). Com
|
|
75
|
+
tarefa em andamento, sair assim é bug: diz, e sai com erro. */
|
|
76
|
+
process.on('beforeExit', () => {
|
|
77
|
+
if (global.__primocodeTarefa) {
|
|
78
|
+
process.stderr.write(`\n ⚠ o PrimoCode ia sair no meio da tarefa (${global.__primocodeTarefa}). Diga "continua" para retomar.\n`);
|
|
79
|
+
process.exitCode = 3;
|
|
80
|
+
global.__primocodeTarefa = null;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
process.on('unhandledRejection', (e) => {
|
|
84
|
+
fala.problema(e instanceof Error ? e : new Error(String(e)));
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// A pasta de onde o comando foi dado. Não é mais onde ele trabalha (o padrão é
|
|
88
|
+
// ~/primocode), mas continua servindo de ponto de partida para achar pasta que
|
|
89
|
+
// o usuário mencionar por nome relativo.
|
|
90
|
+
const CWD_INICIAL = process.cwd();
|
|
91
|
+
|
|
92
|
+
const VERSION = pkg.version;
|
|
93
|
+
|
|
94
|
+
const state = {
|
|
95
|
+
config: cfg.loadConfig(),
|
|
96
|
+
history: [],
|
|
97
|
+
passosProntos: null, // os passos que a pessoa aprovou no /plan: o próximo enviarPedido usa em vez de dividir
|
|
98
|
+
resumindo: null, // o resumo da última rodada, sendo feito em segundo plano
|
|
99
|
+
mode: null, // 'primocode' | 'chat' | 'auto' — vem da config em main()
|
|
100
|
+
modoEfetivo: null, // no auto, o modo que o último pedido usou de fato
|
|
101
|
+
attachedFiles: [],
|
|
102
|
+
// O resumo incremental da conversa — um /compact automático. O porquê
|
|
103
|
+
// está em lib/session/memoria-conversa.js.
|
|
104
|
+
memoria: memoria.nova(),
|
|
105
|
+
// O histórico que o app desktop e o celular enxergam. Cifrado antes de
|
|
106
|
+
// sair daqui; o porquê de cada peça está em lib/nuvem.js.
|
|
107
|
+
gravador: nuvem.gravador({
|
|
108
|
+
// título de 2 a 5 palavras escrito pelo modelo, depois da primeira resposta (lib/session/titulo-conversa.js)
|
|
109
|
+
batizar: (pedido, resposta) => require('../session/titulo-conversa.js').escolher({ pedido, resposta, perguntar: perguntarNome }),
|
|
110
|
+
}),
|
|
111
|
+
/* Começa LIBERADO e a abertura decide depois. Começar bloqueado deixaria
|
|
112
|
+
um instante em que a pessoa digita e leva "sem acesso" antes de o
|
|
113
|
+
plano ter sido conferido — e num pipe, onde a abertura nem roda, o
|
|
114
|
+
bloqueio ficaria para sempre. */
|
|
115
|
+
liberado: true,
|
|
116
|
+
motivoBloqueio: null,
|
|
117
|
+
lastResponse: '',
|
|
118
|
+
trabalhando: false, // o agente está no meio de um pedido (a barra muda)
|
|
119
|
+
/* A autorização para mexer no computador. Vale pela SESSÃO e morre com
|
|
120
|
+
ela: não há arquivo de "sempre permitir" de propósito — autorização
|
|
121
|
+
permanente é exatamente a que ninguém lembra de ter dado. */
|
|
122
|
+
controle: permissao.novo(),
|
|
123
|
+
currentProject: null,
|
|
124
|
+
workDir: null, // pasta onde o agente trabalha nesta sessão
|
|
125
|
+
workDirOrigem: null, // 'padrao' | '/dir' | 'detectada' | 'projeto' | 'terminal' (o -p) — para o /dir explicar
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
/* O /help: os comandos nos 9 grupos de lib/nomes.js, cada um com a descrição
|
|
129
|
+
que o menu já tem (SLASH_COMANDOS + os .md da pessoa e de fábrica). É função
|
|
130
|
+
porque SLASH_COMANDOS nasce depois deste ponto do arquivo. */
|
|
131
|
+
function linhasDosGrupos() {
|
|
132
|
+
const desc = new Map(comandosDoMenu().map(([n, d]) => [n.slice(1), d]));
|
|
133
|
+
const saida = [];
|
|
134
|
+
for (const g of nomes.agrupados()) {
|
|
135
|
+
saida.push(c.bold(g.titulo));
|
|
136
|
+
for (const n of g.comandos) {
|
|
137
|
+
const d = desc.get(n);
|
|
138
|
+
saida.push(d ? ` ${c.brand(ui.padRight('/' + n, 16))}${c.muted(d)}` : ` ${c.brand('/' + n)}`);
|
|
139
|
+
}
|
|
140
|
+
saida.push('');
|
|
141
|
+
}
|
|
142
|
+
return saida;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function montarHelp() {
|
|
146
|
+
return `
|
|
147
|
+
${c.bold('Comandos')} ${c.dim('· os nomes em português continuam valendo (/desfazer = /undo)')}
|
|
148
|
+
|
|
149
|
+
${linhasDosGrupos().join('\n')}
|
|
150
|
+
${c.brand('-p')} "pedido" modo script: sem tela, aceita stdin e --output-format json
|
|
151
|
+
|
|
152
|
+
${c.bold('Modos')}
|
|
153
|
+
${c.warn('Primo Code')} ${c.muted('Agente completo — cria arquivos, roda comandos, abre o navegador')}
|
|
154
|
+
${c.brandDim('Chat')} ${c.muted('Conversa pura — sem tools, só diálogo. Gasta bem menos token')}
|
|
155
|
+
${c.brand('Auto')} ${c.muted('Escolhe por pedido: conversa vai pro chat, tarefa vai pro agente')}
|
|
156
|
+
|
|
157
|
+
${c.bold('Onde ele trabalha')}
|
|
158
|
+
${c.muted('Sempre em')} ${c.warn('~/primocode')}${c.muted(', não importa de onde você abriu o PrimoCode.')}
|
|
159
|
+
${c.muted('Para outra pasta, dois caminhos:')}
|
|
160
|
+
${c.muted(' ·')} ${c.brand('/dir <caminho>')} ${c.muted('aponta para qualquer pasta sua')}
|
|
161
|
+
${c.muted(' ·')} ${c.muted('falar o nome dela no pedido — ele procura no seu computador')}
|
|
162
|
+
${c.dim('Pasta de projeto nova só nasce quando ele vai mexer em arquivo.')}
|
|
163
|
+
`;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ── Autopreenchimento dos comandos (estilo Claude Code) ────────────────
|
|
167
|
+
// Metade do comando já serve: Tab completa, e um prefixo único executa
|
|
168
|
+
// direto — "/eff" vira "/effort" sozinho. A lista é só a dos nomes
|
|
169
|
+
// canônicos; os apelidos (/cd, /stream…) continuam valendo por extenso.
|
|
170
|
+
const SLASH_COMANDOS = [
|
|
171
|
+
['/help', 'todos os comandos · /help all: tudo que ele sabe fazer'],
|
|
172
|
+
['/projects', 'seus projetos, do mais recente · /projects 2 entra · /projects <nome> cria'],
|
|
173
|
+
['/new', 'projeto novo do zero: /new site da padaria · sem nada: 3 perguntas pra quem nunca programou'],
|
|
174
|
+
['/dir', 'trabalhar numa pasta sua'],
|
|
175
|
+
['/worktree', 'cria ../<repo>-<nome> numa branch nova e entra'],
|
|
176
|
+
['/resume', 'retoma uma conversa salva (sem número, lista)'],
|
|
177
|
+
['/sandbox', 'isola os comandos do agente: on | off | rede on | off | status'],
|
|
178
|
+
['/mode', 'primocode | chat | auto'],
|
|
179
|
+
['/effort', 'esforço: low → ultracode (←/→ para ajustar)'],
|
|
180
|
+
['/perms', 'auto | perguntar | livre | plano — quando ele pede licença'],
|
|
181
|
+
['/memory', 'o que ele lembra de você · esquecer <nome> · pasta'],
|
|
182
|
+
['/taste', 'o seu gosto de motion e pra onde ele inclina (refazer, apagar, tirar N) · /taste referencias: ensina com vídeos que você curtiu'],
|
|
183
|
+
['/compact', 'resume a conversa e devolve o contexto'],
|
|
184
|
+
['/init', 'estuda o projeto e escreve o PRIMO.md (as instruções dele)'],
|
|
185
|
+
['/attach', 'anexa um arquivo ou uma página (/attach <url>) · sem nada, lista · /detach tira'],
|
|
186
|
+
['/detach', 'remove os anexos'],
|
|
187
|
+
['/undo', 'desfaz o que o último pedido mudou nos arquivos (lista · N · out)'],
|
|
188
|
+
['/redo', 'volta o que o último /undo desfez'],
|
|
189
|
+
['/check', 'testa o projeto e diz se funcionou (/conferir e /testar ainda valem)'],
|
|
190
|
+
['/restore', 'volta pro último ponto que o /check marcou como funcionando'],
|
|
191
|
+
['/show', 'abre o app no celular de alguém no mesmo Wi-Fi, sem publicar'],
|
|
192
|
+
['/howto', 'escreve no PRIMO.md como abrir e testar este projeto'],
|
|
193
|
+
['/save', 'guarda o projeto no GitHub (privado) e mostra o link · também vale /guardar'],
|
|
194
|
+
['/secrets', 'as chaves que o projeto usa (só os nomes) · /secrets add NOME guarda uma, escondida, no .env · também vale /segredos'],
|
|
195
|
+
['/testar-app', 'sobe o app, abre, clica nos fluxos e conserta os erros (até 2 rodadas)'],
|
|
196
|
+
['/pesquisar', 'relatório com fontes: /pesquisar <tema> grava em pesquisas/'],
|
|
197
|
+
['/placar', 'qual modelo grátis acerta mais em cada tipo de tarefa, aprendido aqui · /placar zerar apaga'],
|
|
198
|
+
['/schedule', 'um pedido que roda sozinho: /schedule "toda segunda às 9h" <pedido> · sem nada, lista · /schedule off 1 tira · também vale /agendar'],
|
|
199
|
+
['/lock', 'arquivos que o agente só pode ler · /lock login.js trava · /lock off login.js solta · sem nada, lista'],
|
|
200
|
+
['/rule', 'uma regra que o PrimoCode segue sempre, mesmo depois de resumir a conversa'],
|
|
201
|
+
['/port', 'o app não abre? diz qual porta responde e o endereço certo'],
|
|
202
|
+
['/map', 'o que tem no projeto, em português, e o que está faltando · /map tree: as pastas'],
|
|
203
|
+
['/explain', 'o que o último pedido mudou, em até 5 linhas · /explain commit: uma palavra · /explain projeto: o projeto todo'],
|
|
204
|
+
['/review', 'revisa o que mudou em duas passadas: acha e depois confere cada achado · /review rápido: uma passada só'],
|
|
205
|
+
['/plan', 'mostra 3 a 5 passos e só começa quando você aperta Enter (ou muda um passo) · /plan <pedido>'],
|
|
206
|
+
['/changes', 'o que mudou no projeto, em português (arquivos e linhas)'],
|
|
207
|
+
['/timeline', 'abre a história do projeto numa página'],
|
|
208
|
+
['/read', 'mostra um arquivo'],
|
|
209
|
+
['/run', 'roda um comando'],
|
|
210
|
+
['/open', 'abre o projeto (sem nada), um arquivo ou um site no navegador'],
|
|
211
|
+
['/export', 'salva a conversa num .md, sem chave nem senha'],
|
|
212
|
+
['/copy', 'copia a última resposta'],
|
|
213
|
+
['/videos', 'seus vídeos prontos (abrir n · pasta n)'],
|
|
214
|
+
['/history', 'procura nos seus pedidos antigos: /history login'],
|
|
215
|
+
['/login', 'entra na sua conta (abre o navegador) · /login senha: e-mail e senha aqui'],
|
|
216
|
+
['/account', 'sua conta e o seu plano · /account plans: os planos e o link para assinar'],
|
|
217
|
+
['/chats', 'suas conversas salvas, as mesmas do app e do celular'],
|
|
218
|
+
['/logout', 'desconecta este computador da conta'],
|
|
219
|
+
['!comando', 'roda direto no shell, sem passar pelo agente (o campo fica âmbar)'],
|
|
220
|
+
['/voice', 'liga o Primo: clique nele e fale; ele faz e responde em voz alta, com a tela dele (robô, agenda, clima, música)'],
|
|
221
|
+
['/voice painel', 'só o painel do Primo (ESC esconde)'],
|
|
222
|
+
['/voice nome <Nome>', 'dá outro nome ao assistente (só o nome; o modo voz abre no clique)'],
|
|
223
|
+
['/voice parar', 'desliga o modo voz e fecha o microfone'],
|
|
224
|
+
['/skills', 'o que ele sabe fazer bem · /skills store: a loja · /skills add <arquivo>: instala'],
|
|
225
|
+
['/commands', 'seus comandos: um .md vira /nome · /commands novo <nome>'],
|
|
226
|
+
['/styles', 'os estilos de motion (kits): a lista e a galeria · /styles <estilo>: o preview dele'],
|
|
227
|
+
['/team', 'trabalhar junto com o claude, codex, gemini, agy ou opencode: /team <nome> liga · /team off'],
|
|
228
|
+
['/api', 'usa a SUA chave (Gemini, ChatGPT, Claude…) direto daqui, sem o limite do servidor'],
|
|
229
|
+
['/offline', 'roda o servidor aqui no seu computador, com as chaves do Render'],
|
|
230
|
+
['/doctor', 'confere se está tudo certo e diz como consertar · /doctor status: só o servidor'],
|
|
231
|
+
['/usage', 'quanto você gastou (agora e hoje) e quando zera · /usage limite 100000 ensina o limite do seu plano'],
|
|
232
|
+
['/tasks', 'o que roda em segundo plano · rodar <cmd> · abrir · parar <id>'],
|
|
233
|
+
['/keys', 'as teclas que ajudam'],
|
|
234
|
+
['/connectors', 'quem está atendendo os seus pedidos'],
|
|
235
|
+
['/name', 'como ele te chama · /name voz <Nome>: o nome do assistente de voz'],
|
|
236
|
+
['/brand', 'kit de marca: cores, fontes e logo'],
|
|
237
|
+
['/mascot', 'galeria dos mascotes · escolha por nome ou número'],
|
|
238
|
+
['/config', 'suas preferências'],
|
|
239
|
+
['/clear', 'limpa a conversa'],
|
|
240
|
+
['/cls', 'limpa a tela'],
|
|
241
|
+
['/uninstall', 'remove o PrimoCode'],
|
|
242
|
+
['/version', 'versão'],
|
|
243
|
+
['/exit', 'sair'],
|
|
244
|
+
];
|
|
245
|
+
|
|
246
|
+
/* /api: a chave da própria pessoa — lib/cli/comando-api.js. */
|
|
247
|
+
const comandoApi = require('./comando-api.js').criar({ rl: () => rl, ask: (...a) => ask(...a), askSecret: (...a) => askSecret(...a) });
|
|
248
|
+
|
|
249
|
+
// ── /effort: o slider de esforço (estilo Claude Code) ──────────────────
|
|
250
|
+
// Régua com os níveis, o marcador ▲ embaixo do escolhido, "Faster" à
|
|
251
|
+
// esquerda e "Smarter" à direita. ←/→ move, Enter confirma, Esc cancela.
|
|
252
|
+
|
|
253
|
+
// O layout sai em texto PLANO, com as marcas de onde pintar. Assim os dois
|
|
254
|
+
// pintores (o normal e o do ultracode animado) desenham exatamente a mesma
|
|
255
|
+
// régua — sem duas contas de posição para manter em sincronia.
|
|
256
|
+
|
|
257
|
+
// Desenha, escuta as setas, e devolve o nome escolhido (ou null se cancelou).
|
|
258
|
+
function sliderEffort(atual) {
|
|
259
|
+
return new Promise((resolve) => {
|
|
260
|
+
if (!process.stdin.isTTY) { // sem terminal (pipe, CI) não há slider
|
|
261
|
+
console.log(c.muted(` Esforço atual: ${effort.normalizar(atual)}. Use /effort <${effort.NOMES.join('|')}>.`));
|
|
262
|
+
return resolve(null);
|
|
263
|
+
}
|
|
264
|
+
let idx = effort.indiceDe(atual);
|
|
265
|
+
const ALTURA = 9; // linhas que o desenho ocupa — para redesenhar por cima
|
|
266
|
+
let fase = 0;
|
|
267
|
+
let anima = null;
|
|
268
|
+
|
|
269
|
+
const pintar = (primeira) => {
|
|
270
|
+
// Na tela cheia o slider desenha no painel dela, acima da caixa.
|
|
271
|
+
if (rl && rl.cheia) return rl.painel(effort.desenharEffort(idx, fase));
|
|
272
|
+
if (!primeira) process.stdout.write(`\x1b[${ALTURA}A\r`);
|
|
273
|
+
process.stdout.write(effort.desenharEffort(idx, fase).split('\n').map((l) => '\x1b[2K' + l).join('\n') + '\n');
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
// O fundo do ultracode ondula; sair dele apaga a animação na hora, para
|
|
277
|
+
// não redesenhar sozinho um painel que já está parado.
|
|
278
|
+
const cuidarDaAnimacao = () => {
|
|
279
|
+
const ultra = effort.NOMES[idx] === 'ultracode';
|
|
280
|
+
if (ultra && !anima) {
|
|
281
|
+
anima = setInterval(() => { fase += 0.32; pintar(false); }, 90);
|
|
282
|
+
anima.unref();
|
|
283
|
+
} else if (!ultra && anima) {
|
|
284
|
+
clearInterval(anima); anima = null;
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
pintar(true);
|
|
289
|
+
cuidarDaAnimacao();
|
|
290
|
+
|
|
291
|
+
const aoTeclar = (ch, key) => {
|
|
292
|
+
if (!key) return;
|
|
293
|
+
if (key.name === 'right' || key.name === 'l') { idx = Math.min(effort.NOMES.length - 1, idx + 1); cuidarDaAnimacao(); pintar(false); return; }
|
|
294
|
+
if (key.name === 'left' || key.name === 'h') { idx = Math.max(0, idx - 1); cuidarDaAnimacao(); pintar(false); return; }
|
|
295
|
+
if (key.name === 'return' || key.name === 'enter') { encerrar(effort.NOMES[idx]); return; }
|
|
296
|
+
if (key.name === 'escape' || (key.ctrl && key.name === 'c')) { encerrar(null); return; }
|
|
297
|
+
};
|
|
298
|
+
const encerrar = (valor) => {
|
|
299
|
+
if (anima) { clearInterval(anima); anima = null; }
|
|
300
|
+
process.stdin.removeListener('keypress', aoTeclar);
|
|
301
|
+
sliderAtivo = false;
|
|
302
|
+
if (rl && rl.retomar) rl.retomar();
|
|
303
|
+
resolve(valor);
|
|
304
|
+
};
|
|
305
|
+
sliderAtivo = true;
|
|
306
|
+
// A caixa sai da frente e larga o teclado: dois desenhos no mesmo
|
|
307
|
+
// lugar, e as setas moveriam os dois ao mesmo tempo.
|
|
308
|
+
if (rl && rl.suspender) rl.suspender();
|
|
309
|
+
process.stdin.on('keypress', aoTeclar);
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function aplicarEffort(nome) {
|
|
314
|
+
const nivel = effort.nivelDe(nome);
|
|
315
|
+
state.config.effort = nivel.nome;
|
|
316
|
+
state.config.model = nivel.model;
|
|
317
|
+
cfg.saveConfig({ effort: nivel.nome, model: nivel.model });
|
|
318
|
+
console.log(c.ok(`Esforço: ${nivel.nome}`) + c.muted(` ${nivel.resumo}`));
|
|
319
|
+
if (nivel.pesquisa) console.log(c.dim(' Pesquisa de referência ligada: ele consulta docs e exemplos antes de escrever.'));
|
|
320
|
+
refreshPrompt();
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Enquanto o slider está no ar, o fantasma do autocompletar não desenha.
|
|
324
|
+
let sliderAtivo = false;
|
|
325
|
+
|
|
326
|
+
/* Os comandos da pessoa (lib/cli/comandos.js), com o do projeto atual por cima.
|
|
327
|
+
A caixa de digitar pede a lista a cada tecla para desenhar o fantasma; um
|
|
328
|
+
cache de dois segundos poupa ler três pastas por letra digitada, e ainda
|
|
329
|
+
pega na hora um arquivo que a pessoa acabou de salvar. */
|
|
330
|
+
let cacheComandos = { em: 0, dir: null, lista: [] };
|
|
331
|
+
function comandosDaPessoa() {
|
|
332
|
+
const agora = Date.now();
|
|
333
|
+
if (agora - cacheComandos.em > 2000 || cacheComandos.dir !== state.workDir) {
|
|
334
|
+
let lista = [];
|
|
335
|
+
try { lista = comandosLib.carregar({ projectDir: state.workDir }); } catch { /* disco estranho não trava a caixa */ }
|
|
336
|
+
cacheComandos = { em: agora, dir: state.workDir, lista };
|
|
337
|
+
}
|
|
338
|
+
return cacheComandos.lista;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/* O menu e o fantasma enxergam os dois tipos. O embutido vem primeiro e,
|
|
342
|
+
com o mesmo nome, o da pessoa nem aparece: quem ganha é sempre o embutido. */
|
|
343
|
+
function comandosDoMenu() {
|
|
344
|
+
const embutidos = new Set(SLASH_COMANDOS.map(([n]) => n));
|
|
345
|
+
const deles = comandosDaPessoa()
|
|
346
|
+
.filter((x) => !embutidos.has('/' + x.nome))
|
|
347
|
+
.map((x) => ['/' + x.nome, x.descricao || `seu comando (${x.origem})`]);
|
|
348
|
+
return SLASH_COMANDOS.concat(deles);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function mostrarMenuSlash() {
|
|
352
|
+
// "/" sozinho mostra as 9 intenções, não a lista seca; o /help tem tudo, com descrição.
|
|
353
|
+
console.log('');
|
|
354
|
+
for (const g of nomes.agrupados()) {
|
|
355
|
+
console.log(` ${c.bold(ui.padRight(g.titulo, 19))}${c.brand(g.comandos.map((n) => '/' + n).join(' '))}`);
|
|
356
|
+
}
|
|
357
|
+
const dela = comandosDaPessoa().filter((x) => !nomes.COMANDOS[x.nome]);
|
|
358
|
+
if (dela.length) console.log(` ${c.bold(ui.padRight('Os seus', 19))}${c.brand(dela.map((x) => '/' + x.nome).join(' '))}`);
|
|
359
|
+
console.log(c.dim('\n /help explica cada um · Tab completa · metade do comando já serve: /eff vira /effort'));
|
|
360
|
+
console.log(c.dim(' Os nomes em português continuam valendo: /undo chama o /undo.'));
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
let rl = null;
|
|
364
|
+
|
|
365
|
+
/* ── A BARRA DE STATUS ───────────────────────────────────────────────────
|
|
366
|
+
* As duas linhas embaixo da caixa de digitar. Elas existem para responder,
|
|
367
|
+
* sem a pessoa perguntar, as coisas que ela erra quando não sabe:
|
|
368
|
+
*
|
|
369
|
+
* · EM QUE PASTA ele está mexendo — de longe o que mais confunde, porque
|
|
370
|
+
* o PrimoCode NÃO trabalha na pasta de onde você o abriu;
|
|
371
|
+
* · em que ramo do git, quando a pasta é um repositório: um agente que
|
|
372
|
+
* escreve arquivo no `main` sem ninguém perceber é o pior tipo de
|
|
373
|
+
* surpresa;
|
|
374
|
+
* · quanto da conversa já foi gasto, para o /compact chegar antes do teto;
|
|
375
|
+
* · qual o modo e qual o esforço, que mudam o que ele pode fazer.
|
|
376
|
+
*
|
|
377
|
+
* A segunda linha é a dos atalhos. Ela repete o que existe porque atalho que
|
|
378
|
+
* a pessoa não vê é atalho que não existe.
|
|
379
|
+
*/
|
|
380
|
+
|
|
381
|
+
// `git rev-parse` a cada quadro seria um processo por tecla digitada. O ramo
|
|
382
|
+
// muda devagar; cinco segundos de atraso não confundem ninguém.
|
|
383
|
+
const ramoCache = new Map();
|
|
384
|
+
function ramoDoGit(dir) {
|
|
385
|
+
if (!dir) return '';
|
|
386
|
+
const guardado = ramoCache.get(dir);
|
|
387
|
+
if (guardado && Date.now() - guardado.quando < 5000) return guardado.ramo;
|
|
388
|
+
let ramo = '';
|
|
389
|
+
try {
|
|
390
|
+
ramo = require('child_process').execSync('git rev-parse --abbrev-ref HEAD', {
|
|
391
|
+
cwd: dir, stdio: ['ignore', 'pipe', 'ignore'], timeout: 1500,
|
|
392
|
+
}).toString().trim();
|
|
393
|
+
} catch { ramo = ''; }
|
|
394
|
+
ramoCache.set(dir, { quando: Date.now(), ramo });
|
|
395
|
+
return ramo;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/* O que a caixa mostra além do texto, no desenho do OpenCode: DENTRO do
|
|
399
|
+
painel, o modo e o esforço ("Auto · alto" — o "Build · Nemotron" de lá);
|
|
400
|
+
FORA, uma linha só, com a pasta e o ramo à esquerda e o contexto e os
|
|
401
|
+
atalhos à direita. A cor da barra do painel é a do modo. */
|
|
402
|
+
const COR_MODO = { auto: '\x1b[38;5;75m', primocode: '\x1b[38;5;216m', chat: '\x1b[38;5;45m' };
|
|
403
|
+
const NOME_MODO = { auto: 'Auto', primocode: 'Primo Code', chat: 'Chat' };
|
|
404
|
+
|
|
405
|
+
function barraDeStatus() {
|
|
406
|
+
const partes = [];
|
|
407
|
+
|
|
408
|
+
// A PASTA, e o ramo do git colado nela ("~/primocode/loja:main"), como
|
|
409
|
+
// o rodapé do OpenCode. Quem apontou com /dir para fora do ~/primocode
|
|
410
|
+
// precisa ver onde está.
|
|
411
|
+
const dir = state.workDir || process.cwd();
|
|
412
|
+
partes.push(c.brandDim(shortPath(dir)));
|
|
413
|
+
const ramo = ramoDoGit(dir);
|
|
414
|
+
if (ramo) partes.push(c.dim('⎇ ' + ramo));
|
|
415
|
+
|
|
416
|
+
if (state.attachedFiles.length) {
|
|
417
|
+
partes.push(c.muted(`+${state.attachedFiles.length} anexo${state.attachedFiles.length > 1 ? 's' : ''}`));
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/* Enquanto o controle do computador está liberado, isso fica escrito na
|
|
421
|
+
barra. Uma autorização que some da vista é uma autorização que a pessoa
|
|
422
|
+
esquece que deu — e ela vale até o PrimoCode fechar. */
|
|
423
|
+
if (state.controle && state.controle.liberado) partes.push(c.warn('controle do pc'));
|
|
424
|
+
|
|
425
|
+
/* O que o agente deixou de pé (run_background). Servidor esquecido segura
|
|
426
|
+
a porta e gasta bateria: tem que estar à vista enquanto roda. */
|
|
427
|
+
const vivos = require('../fundo.js').listar().filter((t) => t.rodando);
|
|
428
|
+
if (vivos.length) {
|
|
429
|
+
const porta = vivos.length === 1 && vivos[0].url && (vivos[0].url.match(/:(\d+)/) || [])[1];
|
|
430
|
+
partes.push(c.ok('●') + ' ' + c.muted(porta ? `de pé :${porta}` : `${vivos.length} de pé`));
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/* O CONTEXTO. Só aparece depois que há conversa: um "ctx 0%" na abertura
|
|
434
|
+
é ruído, e ruído que aparece sempre é o que a pessoa aprende a não
|
|
435
|
+
enxergar — inclusive quando marcar 90%. Âmbar a partir de 70% e
|
|
436
|
+
vermelho a partir de 100%, que é quando `/compact` deixa de ser
|
|
437
|
+
conselho e vira o que fazer. */
|
|
438
|
+
const direita = [];
|
|
439
|
+
const uso = memoria.usoDoContexto(state.memoria, state.history);
|
|
440
|
+
// Modelo que respondeu · contexto · tokens de hoje (os mesmos do /usage) — lib/cli/statusline.js.
|
|
441
|
+
const SL = require('./statusline.js');
|
|
442
|
+
direita.push(...SL.partes({ modelo: SL.modelo(), ctxPct: uso.pct, tokensHoje: SL.tokensDeHoje(), c }));
|
|
443
|
+
direita.push(state.trabalhando && rl && rl.ocupado
|
|
444
|
+
? c.warn('trabalhando') + c.dim(' · ') + c.white('esc esc') + c.dim(' para')
|
|
445
|
+
: c.white('tab') + c.dim(' modos ') + c.white('ctrl+p') + c.dim(' comandos'));
|
|
446
|
+
|
|
447
|
+
/* O modo DENTRO do painel. No auto, depois do primeiro pedido, ele diz
|
|
448
|
+
qual modo acabou respondendo — senão você nunca sabe quem respondeu. */
|
|
449
|
+
const cor = COR_MODO[state.mode] || COR_MODO.auto;
|
|
450
|
+
let modo = `${cor}${NOME_MODO[state.mode] || 'Auto'}${c.reset}`;
|
|
451
|
+
if (state.mode === 'auto' && state.modoEfetivo) {
|
|
452
|
+
modo += c.dim(' → ') + c.muted(NOME_MODO[state.modoEfetivo] || state.modoEfetivo);
|
|
453
|
+
}
|
|
454
|
+
modo += c.dim(' · ') + c.white(effort.normalizar(state.config.effort)) + ' ' + c.dim('PrimoCode');
|
|
455
|
+
|
|
456
|
+
return { modo, cor, esquerda: partes.join(c.dim(' · ')), direita: direita.join(c.dim(' ')) };
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/* A barra da direita da tela cheia, como a do OpenCode: o contexto (quantos
|
|
460
|
+
tokens a conversa já ocupa e quanto isso é do teto), o modo e o esforço, e
|
|
461
|
+
no pé a pasta com o ramo e a versão. */
|
|
462
|
+
function barraLateral() {
|
|
463
|
+
const uso = memoria.usoDoContexto(state.memoria, state.history);
|
|
464
|
+
const dir = state.workDir || process.cwd();
|
|
465
|
+
const ramo = ramoDoGit(dir);
|
|
466
|
+
const m = state.mode === 'auto' && state.modoEfetivo ? state.modoEfetivo : state.mode;
|
|
467
|
+
const secoes = [
|
|
468
|
+
{ titulo: 'Contexto', linhas: [
|
|
469
|
+
c.muted(`${uso.tokens.toLocaleString('pt-BR')} tokens`),
|
|
470
|
+
(uso.pct >= 100 ? c.err : uso.pct >= 70 ? c.warn : c.muted)(`${uso.pct}% usado`),
|
|
471
|
+
] },
|
|
472
|
+
{ titulo: 'Modo', linhas: [
|
|
473
|
+
`${COR_MODO[m] || COR_MODO.auto}${NOME_MODO[m] || m}${c.reset}` + c.muted(` · esforço ${effort.normalizar(state.config.effort)}`),
|
|
474
|
+
] },
|
|
475
|
+
];
|
|
476
|
+
if (state.attachedFiles.length) {
|
|
477
|
+
secoes.push({ titulo: 'Anexos', linhas: state.attachedFiles.map((f) => c.muted(path.basename(f.path))) });
|
|
478
|
+
}
|
|
479
|
+
if (state.controle && state.controle.liberado) secoes.push({ titulo: 'Controle do PC', linhas: [c.warn('liberado até fechar')] });
|
|
480
|
+
return {
|
|
481
|
+
secoes,
|
|
482
|
+
rodape: [
|
|
483
|
+
c.muted(shortPath(dir)) + (ramo ? c.white(':' + ramo) : ''),
|
|
484
|
+
c.brand('●') + ' ' + c.bold(c.white('Primo')) + c.white('Code') + ' ' + c.dim(VERSION),
|
|
485
|
+
],
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/* O Tab com a caixa vazia gira o modo, como o "tab agents" do OpenCode:
|
|
490
|
+
auto → primo code → chat → auto. A escolha fica salva, como a do /mode. */
|
|
491
|
+
function trocarModo() {
|
|
492
|
+
const ordem = ['auto', 'primocode', 'chat'];
|
|
493
|
+
const m = ordem[(ordem.indexOf(state.mode) + 1) % ordem.length];
|
|
494
|
+
state.mode = m;
|
|
495
|
+
state.modoEfetivo = null;
|
|
496
|
+
cfg.saveConfig({ mode: m });
|
|
497
|
+
refreshPrompt();
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// A barra se redesenha sozinha a cada quadro; isto só pede um quadro novo.
|
|
501
|
+
function refreshPrompt() { if (rl) rl.prompt(); }
|
|
502
|
+
|
|
503
|
+
// Enquanto uma pergunta está no ar, a próxima linha digitada é a RESPOSTA dela
|
|
504
|
+
// — não um novo comando. Sem isso o "s" de confirmação virava prompt para a IA.
|
|
505
|
+
let pendingAsk = null;
|
|
506
|
+
|
|
507
|
+
/* ── O QUE A PESSOA ADIANTA ──────────────────────────────────────────────
|
|
508
|
+
* Enquanto a abertura corre — e ela demora, porque confere o plano no
|
|
509
|
+
* servidor — o que for digitado não é comando nem resposta ainda: a pergunta
|
|
510
|
+
* ainda não apareceu. Fica aqui.
|
|
511
|
+
*
|
|
512
|
+
* Sem isto, esse texto caía como PEDIDO no agente. Medido no pacote
|
|
513
|
+
* publicado: o "2" da escolha da IA virou pergunta no chat e o modelo
|
|
514
|
+
* respondeu "Oi! Como posso ajudar?".
|
|
515
|
+
*
|
|
516
|
+
* E guardar não bastava: preso na fila de comandos, ele nunca chegava à
|
|
517
|
+
* pergunta que veio depois. Por isso o `ask` olha aqui ANTES de esperar uma
|
|
518
|
+
* linha nova — quem digitou 2 antes de ver o menu escolheu a 2, e a escolha
|
|
519
|
+
* dela vale.
|
|
520
|
+
*/
|
|
521
|
+
let segurando = false;
|
|
522
|
+
const adiantadas = [];
|
|
523
|
+
|
|
524
|
+
function ask(question) {
|
|
525
|
+
return new Promise((resolve) => {
|
|
526
|
+
if (rl) {
|
|
527
|
+
process.stdout.write(question);
|
|
528
|
+
if (adiantadas.length) { const a = adiantadas.shift(); process.stdout.write(a + '\n'); return resolve(a); }
|
|
529
|
+
pendingAsk = resolve;
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
const tmp = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
533
|
+
tmp.question(question, (a) => { tmp.close(); resolve(a); });
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Pergunta sem mostrar o que se digita — para a senha do /login.
|
|
539
|
+
*
|
|
540
|
+
* Com a caixa de digitar no ar, ela mesma oculta a próxima linha (ver
|
|
541
|
+
* `ocultarProxima` em lib/tui/entrada.js). Sem a caixa, o readline ecoa cada
|
|
542
|
+
* tecla pelo `_writeToOutput`; enquanto a pergunta está aberta, só a quebra
|
|
543
|
+
* de linha passa. Nos dois casos a resposta fica fora do histórico: senão a
|
|
544
|
+
* seta para cima devolveria a senha na tela.
|
|
545
|
+
*/
|
|
546
|
+
function askSecret(question) {
|
|
547
|
+
if (!process.stdin.isTTY) return ask(question);
|
|
548
|
+
if (rl && typeof rl.ocultarProxima === 'function') {
|
|
549
|
+
return new Promise((resolve) => {
|
|
550
|
+
process.stdout.write(question);
|
|
551
|
+
rl.ocultarProxima();
|
|
552
|
+
pendingAsk = resolve;
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
return new Promise((resolve) => {
|
|
556
|
+
const alvo = rl || readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
557
|
+
const original = alvo._writeToOutput;
|
|
558
|
+
process.stdout.write(question);
|
|
559
|
+
alvo._writeToOutput = function (texto) {
|
|
560
|
+
if (/[\r\n]/.test(texto)) original.call(alvo, '\n');
|
|
561
|
+
};
|
|
562
|
+
const fim = (resposta) => {
|
|
563
|
+
alvo._writeToOutput = original;
|
|
564
|
+
if (Array.isArray(alvo.history) && alvo.history[0] === resposta) alvo.history.shift();
|
|
565
|
+
if (!rl) alvo.close();
|
|
566
|
+
resolve(resposta);
|
|
567
|
+
};
|
|
568
|
+
if (rl) pendingAsk = fim;
|
|
569
|
+
else alvo.question('', fim);
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
async function confirm(question) {
|
|
574
|
+
const raw = await ask(`${c.brand('?')} ${question} ${c.muted('(S/n)')} `);
|
|
575
|
+
if (!process.stdin.isTTY) process.stdout.write('\n'); // pipe não ecoa o Enter
|
|
576
|
+
const a = raw.trim().toLowerCase();
|
|
577
|
+
return a === '' || a === 's' || a === 'sim' || a === 'y' || a === 'yes';
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// ── Projetos ───────────────────────────────────────────────────────────
|
|
581
|
+
|
|
582
|
+
/* ── O NOME DO PROJETO ───────────────────────────────────────────────────
|
|
583
|
+
* O nome saía das cinco primeiras palavras depois de "crie um": "agora deixa o
|
|
584
|
+
* carro mais rápido" virava a pasta `agora-deixa-o-carro-mais`, e "oi primo,
|
|
585
|
+
* faz um site" virava `oi-primo-faz-um-site`. Agora o começo da frase
|
|
586
|
+
* (saudação, o nome dele, verbo de pedido, artigo) é pulado, o assunto vai até
|
|
587
|
+
* a primeira palavra que emenda outra ideia ("com", "que", "usando"…), e
|
|
588
|
+
* sobram até quatro palavras que dizem O QUE é: "jogo de carro", "site
|
|
589
|
+
* padaria", "loja roupas". */
|
|
590
|
+
const ABERTURA = new Set([
|
|
591
|
+
'oi', 'ola', 'ei', 'hey', 'e', 'ai', 'primo', 'bom', 'boa', 'dia', 'tarde', 'noite', 'ok', 'beleza',
|
|
592
|
+
'entao', 'agora', 'tipo', 'por', 'favor', 'pfv', 'pf', 'voce', 'vc', 'pode', 'poderia', 'consegue',
|
|
593
|
+
'crie', 'cria', 'criar', 'faca', 'faz', 'fazer', 'monte', 'monta', 'montar', 'desenvolva', 'desenvolver',
|
|
594
|
+
'construa', 'construir', 'gere', 'gera', 'gerar', 'programe', 'programa', 'escreva', 'escreve',
|
|
595
|
+
'quero', 'queria', 'gostaria', 'preciso', 'precisamos', 'vamos', 'bora', 'me', 'pra', 'para', 'mim',
|
|
596
|
+
'um', 'uma', 'uns', 'umas', 'o', 'a', 'os', 'as', 'de', 'novo', 'nova', 'outro', 'outra', 'projeto',
|
|
597
|
+
'simples', 'pequeno', 'pequena', 'rapido', 'bonito', 'bonita',
|
|
598
|
+
// os verbos de CONTINUAR: sem eles, "agora deixa o carro…" virava nome
|
|
599
|
+
'deixa', 'deixe', 'continua', 'continue', 'edita', 'edite', 'muda', 'mude', 'melhora', 'melhore',
|
|
600
|
+
'adiciona', 'adicione', 'coloca', 'coloque', 'poe', 'bota', 'corrige', 'corrija', 'arruma', 'arrume',
|
|
601
|
+
'ajusta', 'ajuste', 'abre', 'abra', 'termina', 'termine',
|
|
602
|
+
]);
|
|
603
|
+
const EMENDA = new Set(['com', 'que', 'usando', 'onde', 'mas', 'porque', 'igual', 'como', 'sobre',
|
|
604
|
+
'em', 'no', 'na', 'nos', 'nas', 'e', 'tipo', 'estilo', 'feito', 'utilizando', 'mais', 'menos']);
|
|
605
|
+
// Palavras que não dizem o que a coisa É — saem de qualquer posição.
|
|
606
|
+
const DE_ENCHER = new Set(['minha', 'meu', 'minhas', 'meus', 'nossa', 'nosso', 'para', 'pra', 'uma', 'um',
|
|
607
|
+
'simples', 'bonito', 'bonita', 'pequeno', 'pequena', 'legal', 'rapido', 'rapida', 'basico', 'basica',
|
|
608
|
+
'completo', 'completa', 'novo', 'nova']);
|
|
609
|
+
|
|
610
|
+
function semAcento(x) { return String(x || '').normalize('NFD').replace(/[̀-ͯ]/g, '').toLowerCase(); }
|
|
611
|
+
|
|
612
|
+
function deriveProjectName(text) {
|
|
613
|
+
const palavras = String(text || '').split(/\s+/)
|
|
614
|
+
.map((w) => w.replace(/[^\wáéíóúâêôãõçÁÉÍÓÚÂÊÔÃÕÇ-]/gi, ''))
|
|
615
|
+
.filter(Boolean);
|
|
616
|
+
let i = 0;
|
|
617
|
+
while (i < palavras.length && ABERTURA.has(semAcento(palavras[i]))) i++;
|
|
618
|
+
const assunto = [];
|
|
619
|
+
for (; i < palavras.length && assunto.length < 6; i++) {
|
|
620
|
+
const w = semAcento(palavras[i]);
|
|
621
|
+
if (assunto.length && EMENDA.has(w)) break;
|
|
622
|
+
if (DE_ENCHER.has(w)) continue;
|
|
623
|
+
assunto.push(palavras[i]);
|
|
624
|
+
}
|
|
625
|
+
while (assunto.length && /^(de|do|da|dos|das)$/i.test(semAcento(assunto[assunto.length - 1]))) assunto.pop();
|
|
626
|
+
const nome = assunto.slice(0, 4).join(' ').trim();
|
|
627
|
+
return nome || 'projeto';
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/* ── "CRIE UM…" DENTRO DE UM PROJETO ────────────────────────────────────
|
|
631
|
+
* Depois de entrar num projeto, TUDO ia para ele — até "crie um site de
|
|
632
|
+
* receitas" no meio do jogo de carro. E fora dele, qualquer "continua" virava
|
|
633
|
+
* projeto novo. A regra agora: dentro de um projeto, só um pedido que CLARAMENTE
|
|
634
|
+
* abre outra coisa sai dele — verbo de criar + "um/uma/outro/novo", assunto
|
|
635
|
+
* que não tem nada a ver com o projeto atual, e nenhuma referência a ele
|
|
636
|
+
* ("isso", "esse", "nele"). Todo o resto ("continua", "muda a cor", "agora
|
|
637
|
+
* põe fases") fica. */
|
|
638
|
+
const RE_PROJETO_NOVO = /\b(novo projeto|projeto novo|outro projeto|do zero|come[cç]a(r)? (um|uma|outro|outra))\b/;
|
|
639
|
+
/* "crie UM site…" e também "crie O SITE da barbearia": o artigo definido com
|
|
640
|
+
o tipo da coisa é projeto novo com nome (medido em 29/09: "crie o site
|
|
641
|
+
bench-barbearia" nasceu DENTRO do projeto que estava aberto). Se for o
|
|
642
|
+
mesmo assunto do projeto atual, a comparação de assunto em pedeProjetoNovo
|
|
643
|
+
segura como continuação. */
|
|
644
|
+
const RE_CRIAR_UM = /\b(crie|cria|criar|fa[cç]a|faz|fazer|monte|monta|montar|gere|gera|desenvolva|construa|programe|quero|preciso de)\s+(um|uma|outro|outra|novo|nova|(o|a)\s+(site|app|aplicativo|jogo|projeto|landing|pagina|sistema|loja|dashboard|painel))\b/;
|
|
645
|
+
const RE_REFERE_ATUAL = /\b(isso|isto|esse|essa|este|esta|nele|nela|dele|dela|no projeto|nesse|nessa|neste|nesta|continua|continue|edita|edite|muda|mude|melhora|melhore|adiciona|adicione|coloca|coloque|p[oõ]e|corrige|corrija|arruma|arrume|ajusta|ajuste)\b/;
|
|
646
|
+
|
|
647
|
+
/* "crie uma nova seção", "cria um botão", "faz uma tela de login": é um
|
|
648
|
+
PEDAÇO do projeto em que se está, não outro projeto. */
|
|
649
|
+
const RE_PEDACO = /\b(um|uma|outro|outra|novo|nova)\s+(nov[ao]\s+)?(secao|secoes|parte|botao|botoes|tela|aba|menu|rodape|cabecalho|formulario|fase|funcao|funcionalidade|campo|imagem|animacao|efeito|cor|fonte|pagina interna|area|bloco|card|modal|link)\b/;
|
|
650
|
+
|
|
651
|
+
function pedeProjetoNovo(texto) {
|
|
652
|
+
const t = semAcento(texto);
|
|
653
|
+
if (RE_PROJETO_NOVO.test(t)) return true;
|
|
654
|
+
if (!RE_CRIAR_UM.test(t) || RE_REFERE_ATUAL.test(t) || RE_PEDACO.test(t)) return false;
|
|
655
|
+
// Mesmo assunto do projeto atual ("crie uma fase nova pro jogo de carro")
|
|
656
|
+
// é continuação, não projeto novo.
|
|
657
|
+
const atual = new Set(cfg.tokensDoAssunto(state.currentProject || ''));
|
|
658
|
+
const pedido = cfg.tokensDoAssunto(deriveProjectName(texto));
|
|
659
|
+
return !pedido.some((x) => atual.has(x));
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/* Pedido de mexer no computador da pessoa (abrir app, clicar, digitar,
|
|
663
|
+
mostrar o cursor). Serve só para mandar a dica das ferramentas desktop_*. */
|
|
664
|
+
const RE_COMPUTADOR = /\b(abr[ae]|abrir|clica|clique|clicar|digita|digite|digitar|mouse|cursor|teclado|meu computador|no (meu )?mac|na (minha )?tela|aplicativo|spotify|safari|finder|whatsapp|mensagens|m[úu]sica|configura[çc][õo]es|ajustes)\b/i;
|
|
665
|
+
function querComputador(texto) { return RE_COMPUTADOR.test(String(texto || '')); }
|
|
666
|
+
|
|
667
|
+
/* Pedido de VER o navegador ("abre o youtube", "entra no site x", "testa no
|
|
668
|
+
Chrome"). Sem isto as ferramentas browser_* rodam escondidas: pesquisar e
|
|
669
|
+
conferir não precisam abrir aba na tela da pessoa (02/10). */
|
|
670
|
+
const RE_NAVEGADOR = /\b(navegador|chrome|browser|edge|brave|aba|abas|youtube|gmail|instagram|facebook|linkedin|login|loga|logar|(abr[ae]|abrir|entr[ae]|entrar|acess[ae]|acessar|mostr[ae]|testa|testar)\b[^.?!]{0,25}\b(site|p[áa]gina|link|url|google|navegador))\b/i;
|
|
671
|
+
function querNavegador(texto) { return RE_NAVEGADOR.test(String(texto || '')); }
|
|
672
|
+
|
|
673
|
+
/* Guarda onde se está, para a próxima sessão continuar aqui. */
|
|
674
|
+
function entrarNoProjeto(dir, origem = 'projeto') {
|
|
675
|
+
state.workDir = dir;
|
|
676
|
+
state.currentProject = path.basename(dir);
|
|
677
|
+
state.workDirOrigem = origem;
|
|
678
|
+
cfg.lembrarProjeto(dir, origem);
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// Pasta em que é seguro deixar um agente criar e editar arquivo. A home e a raiz
|
|
682
|
+
// do disco não contam — ninguém quer um agente soltando arquivo no meio de
|
|
683
|
+
// C:\Users\você. O ~/primocode ERA recusado aqui, de quando a pasta atual do
|
|
684
|
+
// terminal era adotada; hoje ele é o padrão, então recusá-lo não faz sentido.
|
|
685
|
+
function pastaSegura(dir) {
|
|
686
|
+
const home = os.homedir();
|
|
687
|
+
const resolved = path.resolve(dir);
|
|
688
|
+
if (resolved === path.resolve(home)) return false;
|
|
689
|
+
if (resolved === path.parse(resolved).root) return false;
|
|
690
|
+
return true;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
// Escolhe onde trabalhar SEM criar nada.
|
|
694
|
+
//
|
|
695
|
+
// Três casos, nesta ordem:
|
|
696
|
+
// 1. pasta escolhida a dedo (/dir, ou detectada no pedido) — manda, sempre.
|
|
697
|
+
// 2. projeto que JÁ existe e parece com o pedido — entra nele agora, senão a
|
|
698
|
+
// memory.md dele não carrega neste turno.
|
|
699
|
+
// 3. projeto novo — fica PENDENTE: age em ~/primocode e só cria a pasta se o
|
|
700
|
+
// agente for mexer em arquivo. Pedir para abrir o Chrome não cria projeto.
|
|
701
|
+
// Pedido que se resolve DENTRO do estúdio: vídeo, slides, arte, documento,
|
|
702
|
+
// planilha, diagrama. O que sai dali já é guardado pelo próprio estúdio, em
|
|
703
|
+
// ~/.primocode/studio/arquivos — não precisa (e não deve) virar pasta de
|
|
704
|
+
// código em ~/primocode, cheia de memory.md sobre um vídeo.
|
|
705
|
+
const PEDIDO_DE_ESTUDIO = /\b(v[íi]deo|reels?|anima[çc][ãa]o|slides?|apresenta[çc][ãa]o|deck|post|banner|capa|thumbnail|arte|cartaz|planilha|documento|relat[óo]rio|diagrama|fluxograma|narra[çc][ãa]o|est[úu]dio)\b/i;
|
|
706
|
+
// ...a menos que ele também peça código ou página: aí é projeto de verdade.
|
|
707
|
+
const PEDIDO_DE_CODIGO = /\b(html|css|javascript|js|react|next|python|api|site|p[áa]gina|app|aplicativo|script|reposit[óo]rio|c[óo]digo|programa|servidor|banco de dados)\b/i;
|
|
708
|
+
|
|
709
|
+
function ehSoEstudio(texto) {
|
|
710
|
+
const t = String(texto || '');
|
|
711
|
+
return PEDIDO_DE_ESTUDIO.test(t) && !PEDIDO_DE_CODIGO.test(t);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
function planWorkDir(userText) {
|
|
715
|
+
// O /novo já criou a pasta e entrou nela: nenhuma heurística decide outra.
|
|
716
|
+
if (state.projetoFixo) return { dir: state.workDir, pending: false, name: state.currentProject };
|
|
717
|
+
const escolhida = ['/dir', 'detectada', 'projeto', 'terminal'].includes(state.workDirOrigem);
|
|
718
|
+
// Pasta escolhida a dedo (/dir, ou dita no pedido) manda sempre. Projeto
|
|
719
|
+
// em andamento manda também — a menos que o pedido abra outra coisa.
|
|
720
|
+
if (escolhida && !(state.workDirOrigem === 'projeto' && pedeProjetoNovo(userText))) {
|
|
721
|
+
return { dir: state.workDir, pending: false, name: state.currentProject };
|
|
722
|
+
}
|
|
723
|
+
// "Quando eu peço um vídeo, não é pra ficar com projeto. Só vai criar
|
|
724
|
+
// projeto quando tiver um HTML, quando tiver um código."
|
|
725
|
+
if (ehSoEstudio(userText)) {
|
|
726
|
+
return { dir: cfg.ROOT_DIR, pending: false, name: state.currentProject, estudio: true };
|
|
727
|
+
}
|
|
728
|
+
const proposto = deriveProjectName(userText);
|
|
729
|
+
const parecido = cfg.findSimilarProject(proposto);
|
|
730
|
+
if (parecido) return { dir: parecido.dir, pending: false, name: parecido.name, similar: true };
|
|
731
|
+
return { dir: cfg.ROOT_DIR, projeto: cfg.getProjectDir(proposto), pending: true, name: proposto };
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
/* O nome da pasta nova vem do modelo (lib/nome-projeto.js), pedido em
|
|
735
|
+
paralelo com o trabalho: a pasta só nasce na primeira escrita, e até lá a
|
|
736
|
+
resposta já chegou. Só pergunta quando o pedido é de CRIAR algo — pedir
|
|
737
|
+
para abrir o Chrome não gasta chamada com nome de pasta. */
|
|
738
|
+
async function perguntarNome(texto) {
|
|
739
|
+
let resposta = '';
|
|
740
|
+
await api.requestChat(state.config.server, {
|
|
741
|
+
prompt: texto, history: [], model: state.config.model, token: state.config.token,
|
|
742
|
+
}, (evt) => { if (evt.delta) resposta += evt.delta; });
|
|
743
|
+
return resposta;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
/* O corpo do /novo, num lugar só: o /comecar também cria a pasta e roda o
|
|
747
|
+
pedido preso nela, e dois caminhos copiados divergiriam. */
|
|
748
|
+
async function criarProjetoNovo(rest) {
|
|
749
|
+
const nomes = cfg.listProjects();
|
|
750
|
+
const sp = new Spinner('escolhendo o nome da pasta').start();
|
|
751
|
+
const sugerido = await nomeProjeto.escolher({ pedido: rest, nomes, perguntar: perguntarNome }).catch(() => null);
|
|
752
|
+
sp.stop();
|
|
753
|
+
const nomeNovo = extra.nomeDoNovo({
|
|
754
|
+
descricao: rest, nomes, sugerido, derivar: deriveProjectName,
|
|
755
|
+
// A régua curta (lib/nome-curto.js) também no /novo.
|
|
756
|
+
slugify: (t) => nomeCurto(t) || cfg.slugify(t), semColisao: nomeProjeto.semColisao,
|
|
757
|
+
});
|
|
758
|
+
const dir = cfg.createProjectDir(nomeNovo);
|
|
759
|
+
entrarNoProjeto(dir, 'projeto');
|
|
760
|
+
// Conversa nova junto: o que se falou do projeto anterior puxaria o
|
|
761
|
+
// agente de volta para ele.
|
|
762
|
+
state.history = []; state.memoria = memoria.nova(); state.gravador.zerar();
|
|
763
|
+
console.log(c.ok(` Projeto novo: ${state.currentProject}`) + c.muted(` (${shortPath(dir)})`));
|
|
764
|
+
refreshPrompt();
|
|
765
|
+
const modoAntes = state.mode;
|
|
766
|
+
state.mode = 'primocode';
|
|
767
|
+
state.projetoFixo = true;
|
|
768
|
+
try { await sendPrompt(extra.pedidoDoNovo(rest, state.currentProject)); }
|
|
769
|
+
finally { state.mode = modoAntes; state.projetoFixo = false; }
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
function batizarDepois(plan, userText) {
|
|
773
|
+
if (!plan.pending || !(RE_CRIAR_UM.test(semAcento(userText)) || PEDIDO_DE_CODIGO.test(userText))) return;
|
|
774
|
+
plan.batizando = nomeProjeto.escolher({ pedido: userText, nomes: cfg.listProjects(), perguntar: perguntarNome })
|
|
775
|
+
.then((nome) => { if (nome) plan.nomeEscolhido = nome; });
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
function createPendingProject(plan) {
|
|
779
|
+
const dir = cfg.createProjectDir(plan.nomeEscolhido || plan.name);
|
|
780
|
+
entrarNoProjeto(dir, 'projeto');
|
|
781
|
+
const rotulo = plan.similar ? 'Continuando em' : 'Projeto novo:';
|
|
782
|
+
console.log(c.ok(` ${rotulo} ${state.currentProject}`) + c.muted(` (${dir})`));
|
|
783
|
+
refreshPrompt();
|
|
784
|
+
return dir;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
function projectDir() {
|
|
788
|
+
return state.workDir || process.cwd();
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
// ── Envio ──────────────────────────────────────────────────────────────
|
|
792
|
+
|
|
793
|
+
/**
|
|
794
|
+
* Falou de OUTRA pasta? Ele LÊ lá sem pedir, e só TROCA com o seu sim.
|
|
795
|
+
*
|
|
796
|
+
* "Quando eu perguntar de algo de outra pasta, ela vai procurar lá; e se ela
|
|
797
|
+
* está aberta numa pasta e eu trabalho em outra, ela muda — com permissão."
|
|
798
|
+
* A pasta citada (caminho, "pasta X", ou o nome de um projeto/pasta recente)
|
|
799
|
+
* fica liberada para leitura (lib/tool/tools.js). A troca pergunta, Enter é NÃO.
|
|
800
|
+
*
|
|
801
|
+
* Devolve a nota para o modelo quando a pessoa ficou onde estava — é ela que
|
|
802
|
+
* diz ao agente que pode procurar lá. Com mais de uma pasta do mesmo nome,
|
|
803
|
+
* lista e espera o /dir: heurística não escolhe onde o agente escreve.
|
|
804
|
+
*/
|
|
805
|
+
async function talvezTrocarDePasta(userText) {
|
|
806
|
+
const r = outraPasta.detectar(userText, {
|
|
807
|
+
conhecidas: outraPasta.conhecidas({ raiz: cfg.ROOT_DIR, recentes: cfg.pastasRecentes() }),
|
|
808
|
+
atual: projectDir(),
|
|
809
|
+
resolver: (cand) => pasta.resolverPasta(cand, { raiz: cfg.ROOT_DIR, cwd: CWD_INICIAL }),
|
|
810
|
+
});
|
|
811
|
+
if (r.ambiguo) {
|
|
812
|
+
console.log(c.warn(` Achei ${r.ambiguo.length} pastas chamadas "${r.candidato}":`));
|
|
813
|
+
r.ambiguo.forEach((a) => console.log(` ${c.dim('·')} ${c.white(shortPath(a.caminho))}`));
|
|
814
|
+
console.log(c.dim(' Escolha com /dir <caminho>.'));
|
|
815
|
+
return '';
|
|
816
|
+
}
|
|
817
|
+
const alvo = (r.pastas || []).find((p) => pastaSegura(p.caminho));
|
|
818
|
+
if (!alvo) return ''; // home ou raiz: só por /dir explícito
|
|
819
|
+
|
|
820
|
+
/* Ler lá só se libera DEPOIS do sim (a troca): recusa não destrava nada. */
|
|
821
|
+
|
|
822
|
+
/* No pedido único (`primocode "crie x na pasta loja"`) não há a quem
|
|
823
|
+
perguntar — e a pasta veio escrita no próprio comando, com marca
|
|
824
|
+
("pasta", caminho). Aí vale o que ele sempre fez: troca. Nome solto
|
|
825
|
+
("olha o landing-padaria") nunca troca sem pergunta. */
|
|
826
|
+
if (state.semTerminal) {
|
|
827
|
+
if (alvo.como !== 'caminho') return '';
|
|
828
|
+
entrarNoProjeto(alvo.caminho, 'detectada');
|
|
829
|
+
return '';
|
|
830
|
+
}
|
|
831
|
+
console.log(c.dim(` ⎿ você citou ${shortPath(alvo.caminho)}`));
|
|
832
|
+
if (!(await perguntarTroca(alvo.caminho))) return '';
|
|
833
|
+
trocarPara(alvo.caminho, 'detectada', `você falou "${alvo.nome}"`);
|
|
834
|
+
return '';
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
/* A pergunta da troca. Enter sozinho é NÃO: trocar muda onde os arquivos
|
|
838
|
+
nascem, e o padrão de quem apertou Enter sem ler não pode ser esse. */
|
|
839
|
+
async function perguntarTroca(caminho, motivo = '') {
|
|
840
|
+
if (motivo) console.log(' ' + c.muted(motivo));
|
|
841
|
+
const dito = String(await ask(`${c.brand('?')} Trabalhar em ${c.white(shortPath(caminho))} a partir de agora? ${c.muted('(s/N)')} `))
|
|
842
|
+
.trim().toLowerCase().replace(/[.!?,;:…]+/g, ' ').trim();
|
|
843
|
+
if (!process.stdin.isTTY) process.stdout.write('\n');
|
|
844
|
+
return /^(s|sim|y|yes|pode|ok|claro|muda|troca)\b/.test(dito);
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
/* Entra na pasta e avisa. A memória dela (AGENTS.md) entra no próximo
|
|
848
|
+
pedido pelo buildMemoryContext, porque ainda não está no resumo. */
|
|
849
|
+
function trocarPara(caminho, origem, porque) {
|
|
850
|
+
entrarNoProjeto(caminho, origem);
|
|
851
|
+
const tem = agentsMd.ler(caminho) ? ' · com memória das sessões anteriores' : '';
|
|
852
|
+
console.log(c.ok(` Trabalhando em ${shortPath(caminho)}`) + c.dim(` (${porque}${tem})`));
|
|
853
|
+
refreshPrompt();
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
/* Servidor MCP do .mcp.json do PROJETO: roda comando na máquina, então pergunta
|
|
857
|
+
mesmo no auto (lib/mcp/mcp.js lembra o sim por projeto + configuração). */
|
|
858
|
+
require('../mcp/mcp.js').usarPerguntador(async ({ nome, resumo }) => {
|
|
859
|
+
if (state.semTerminal) return false;
|
|
860
|
+
console.log('');
|
|
861
|
+
console.log(' ' + c.warn('▸▸') + ' ' + c.bold(c.white(`O .mcp.json deste projeto quer rodar o servidor "${nome}".`)));
|
|
862
|
+
console.log(' ' + c.dim(resumo.slice(0, 200)));
|
|
863
|
+
const dito = String(await ask(`${c.brand('?')} Deixar rodar? ${c.muted('(s/N)')} `)).trim().toLowerCase();
|
|
864
|
+
if (!process.stdin.isTTY) process.stdout.write('\n');
|
|
865
|
+
return /^(s|sim|y|yes)\b/.test(dito);
|
|
866
|
+
});
|
|
867
|
+
|
|
868
|
+
/* O mudar_pasta do modelo chega aqui (lib/outra-pasta.js → pedirTroca). */
|
|
869
|
+
async function mudarPastaPeloAgente({ caminho, motivo }) {
|
|
870
|
+
if (state.semTerminal) return { ok: false, error: 'sem terminal para o usuário responder.' };
|
|
871
|
+
console.log('');
|
|
872
|
+
console.log(' ' + c.warn('▸▸') + ' ' + c.bold(c.white('O Primo quer trabalhar em outra pasta.')));
|
|
873
|
+
if (!(await perguntarTroca(caminho, motivo ? `Motivo: ${motivo}` : ''))) {
|
|
874
|
+
console.log(' ' + c.muted('Fica onde está.'));
|
|
875
|
+
return { ok: false };
|
|
876
|
+
}
|
|
877
|
+
trocarPara(caminho, 'detectada', 'você autorizou');
|
|
878
|
+
return { ok: true, caminho, memoria: agentsMd.ler(caminho) || undefined };
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
/**
|
|
882
|
+
* Decide, de uma vez, onde este pedido vai trabalhar.
|
|
883
|
+
*
|
|
884
|
+
* ESTA É A ÚNICA função que decide pasta. Existiam duas cópias — uma no
|
|
885
|
+
* sendPrompt e outra no modo um-tiro — e a do um-tiro ficou sem a detecção: pedir
|
|
886
|
+
* `primocode "crie x na pasta loja"` ignorava a pasta e criava projeto novo.
|
|
887
|
+
* Duas cópias da mesma decisão significam que uma delas está errada.
|
|
888
|
+
*/
|
|
889
|
+
async function prepararPasta(userText) {
|
|
890
|
+
// A pasta é decidida ANTES de o agente começar. Trocar no meio faria as
|
|
891
|
+
// primeiras tools agirem num lugar e as seguintes em outro.
|
|
892
|
+
const notaOutraPasta = await talvezTrocarDePasta(userText);
|
|
893
|
+
|
|
894
|
+
const plan = planWorkDir(userText);
|
|
895
|
+
batizarDepois(plan, userText);
|
|
896
|
+
|
|
897
|
+
// Projeto que já existe: entra nele AGORA. Se deixasse para depois, o
|
|
898
|
+
// buildMemoryContext deste turno leria a pasta errada e a memória do projeto
|
|
899
|
+
// não carregaria.
|
|
900
|
+
if (!plan.pending && path.resolve(plan.dir) !== path.resolve(projectDir())) {
|
|
901
|
+
entrarNoProjeto(plan.dir, 'projeto');
|
|
902
|
+
console.log(c.ok(` Continuando em ${state.currentProject}`) + c.muted(` (${shortPath(plan.dir)})`));
|
|
903
|
+
refreshPrompt();
|
|
904
|
+
}
|
|
905
|
+
plan.notaOutraPasta = notaOutraPasta;
|
|
906
|
+
return plan;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
/* ── O PEDIDO PARA MEXER NO COMPUTADOR ───────────────────────────────────
|
|
910
|
+
* Três respostas: agora, a sessão inteira, não.
|
|
911
|
+
*
|
|
912
|
+
* A do meio existe porque uma tarefa de desktop são dez, vinte ações. Pedir a
|
|
913
|
+
* cada clique transforma a permissão num botão que se aperta sem ler — o
|
|
914
|
+
* mesmo que não pedir, com uma etapa a mais. Uma vez, com o que ele vai fazer
|
|
915
|
+
* escrito, é a pergunta que ainda é lida.
|
|
916
|
+
*
|
|
917
|
+
* Enter sozinho é NÃO. O padrão de quem apertou Enter sem ler não pode ser
|
|
918
|
+
* entregar o mouse e o teclado.
|
|
919
|
+
*/
|
|
920
|
+
async function autorizarControle(oQueVaiFazer, { primeira, tipo } = {}) {
|
|
921
|
+
/* O mesmo portão serve ao /permissoes (lib/permission/perigo.js): a pergunta muda de
|
|
922
|
+
cabeçalho, as três respostas são as mesmas. */
|
|
923
|
+
if (tipo) {
|
|
924
|
+
console.log('');
|
|
925
|
+
console.log(' ' + c.warn('▸▸') + ' ' + c.bold(c.white(tipo === 'perigo'
|
|
926
|
+
? 'Isto não tem volta. O Primo quer:'
|
|
927
|
+
: 'O Primo quer (você escolheu /perms perguntar):')));
|
|
928
|
+
} else if (primeira) {
|
|
929
|
+
console.log('');
|
|
930
|
+
console.log(' ' + c.warn('▸▸') + ' ' + c.bold(c.white('O Primo quer usar o seu computador.')));
|
|
931
|
+
console.log(' ' + c.muted('Ele vai mexer no mouse e no teclado de verdade, no programa que'));
|
|
932
|
+
console.log(' ' + c.muted('estiver na frente. Você vê cada passo aqui enquanto acontece.'));
|
|
933
|
+
}
|
|
934
|
+
console.log('');
|
|
935
|
+
console.log(' ' + c.brand('●') + ' ' + c.white(oQueVaiFazer));
|
|
936
|
+
console.log(' ' + c.dim('1') + c.muted(' agora ')
|
|
937
|
+
+ c.dim('2') + c.muted(' esta sessão inteira ')
|
|
938
|
+
+ c.dim('Enter') + c.muted(' não'));
|
|
939
|
+
|
|
940
|
+
// Sem pontuação: a resposta pode vir FALADA (/voice), e o Whisper devolve
|
|
941
|
+
// "Sim." e "Pode, sim." — que também são sim.
|
|
942
|
+
const dito = String(await ask(' ' + c.brand('❯ ') + c.muted('1, 2 ou Enter '))).trim().toLowerCase()
|
|
943
|
+
.replace(/[.!?,;:…]+/g, ' ').replace(/\s+/g, ' ').trim();
|
|
944
|
+
if (/sess|sempre|tudo|todas/.test(dito) && dito !== '1') {
|
|
945
|
+
console.log(' ' + c.ok('✔ autorizado') + c.dim(' — esta sessão inteira. Fechar o PrimoCode esquece.'));
|
|
946
|
+
return 'sessao';
|
|
947
|
+
}
|
|
948
|
+
if (dito === '1' || /^(s|sim|ok|pode|agora|y|yes|claro|vai)\b/.test(dito)) {
|
|
949
|
+
console.log(' ' + c.ok('✔ autorizado') + c.dim(' — só esta ação'));
|
|
950
|
+
return 'agora';
|
|
951
|
+
}
|
|
952
|
+
if (dito === '2' || /sess|sempre|tudo|todas/.test(dito)) {
|
|
953
|
+
console.log(' ' + c.ok('✔ autorizado') + c.dim(' — esta sessão inteira. Fechar o PrimoCode esquece.'));
|
|
954
|
+
return 'sessao';
|
|
955
|
+
}
|
|
956
|
+
console.log(' ' + c.muted('Não autorizado.') + c.dim(' Ele vai resolver por outro caminho.'));
|
|
957
|
+
return 'nao';
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
/* ── A TELA DO MARKETPLACE ───────────────────────────────────────────────
|
|
961
|
+
* O desenho e as teclas vivem em lib/skill/marketplace.js, que é função pura. O que
|
|
962
|
+
* mora aqui é o que precisa do terminal: tirar a caixa de digitar da frente,
|
|
963
|
+
* escutar as setas, e fazer o que a tela pediu (ligar uma skill, abrir o
|
|
964
|
+
* diálogo de criar).
|
|
965
|
+
*
|
|
966
|
+
* A divisão é a mesma do /effort, e pelo mesmo motivo: dois desenhos no mesmo
|
|
967
|
+
* lugar brigam pelo teclado e pelo cursor.
|
|
968
|
+
*/
|
|
969
|
+
function abrirMarketplace() {
|
|
970
|
+
return new Promise((resolve) => {
|
|
971
|
+
if (!process.stdin.isTTY) {
|
|
972
|
+
// Sem terminal não há seta para apertar. Cair no /skills é melhor
|
|
973
|
+
// que desenhar uma tela que ninguém pode usar.
|
|
974
|
+
return handleSlash('/skills').then(resolve);
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
let estado = marketplace.novo(skills.listar());
|
|
978
|
+
const altura = () => Math.max(6, Math.min(16, (process.stdout.rows || 24) - 10));
|
|
979
|
+
let alturaDesenhada = 0;
|
|
980
|
+
|
|
981
|
+
const pintar = (primeira) => {
|
|
982
|
+
const texto = marketplace.montar(estado, {
|
|
983
|
+
colunas: process.stdout.columns || 80, altura: altura(),
|
|
984
|
+
});
|
|
985
|
+
if (rl && rl.cheia) return rl.painel(texto);
|
|
986
|
+
const linhas = texto.split('\n');
|
|
987
|
+
// Redesenha POR CIMA do quadro anterior em vez de rolar a tela:
|
|
988
|
+
// sem isso, cada seta empurraria a tela inteira para cima e o
|
|
989
|
+
// terminal viraria um rolo de cópias do marketplace.
|
|
990
|
+
if (!primeira && alturaDesenhada) process.stdout.write(`\x1b[${alturaDesenhada}A\r`);
|
|
991
|
+
process.stdout.write(linhas.map((l) => '\x1b[2K' + l).join('\n') + '\n');
|
|
992
|
+
// O quadro novo pode ser mais curto que o anterior (a descrição
|
|
993
|
+
// que some ao mudar de item): o resto é apagado, senão sobra
|
|
994
|
+
// lixo da linha antiga embaixo.
|
|
995
|
+
if (alturaDesenhada > linhas.length) {
|
|
996
|
+
const sobra = alturaDesenhada - linhas.length;
|
|
997
|
+
process.stdout.write('\x1b[2K\n'.repeat(sobra) + `\x1b[${sobra}A`);
|
|
998
|
+
}
|
|
999
|
+
alturaDesenhada = Math.max(linhas.length, alturaDesenhada);
|
|
1000
|
+
};
|
|
1001
|
+
|
|
1002
|
+
const aoTeclar = (ch, key) => {
|
|
1003
|
+
if (!key) return;
|
|
1004
|
+
const { estado: novoEstado, acao } = marketplace.andar(estado, key, { altura: altura() });
|
|
1005
|
+
estado = novoEstado;
|
|
1006
|
+
|
|
1007
|
+
if (!acao) { pintar(false); return; }
|
|
1008
|
+
|
|
1009
|
+
if (acao.tipo === 'fechar') { encerrar(); resolve(); return; }
|
|
1010
|
+
|
|
1011
|
+
if (acao.tipo === 'alternar') {
|
|
1012
|
+
skills.ligar(acao.skill.nome, !acao.skill.ligada);
|
|
1013
|
+
// A lista é relida do disco: a skill muda de seção, e a tela
|
|
1014
|
+
// tem de mostrar isso na hora — senão parece que nada
|
|
1015
|
+
// aconteceu e a pessoa aperta Enter de novo.
|
|
1016
|
+
estado = { ...estado, skills: skills.listar() };
|
|
1017
|
+
pintar(false);
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
if (acao.tipo === 'nova' || acao.tipo === 'instalar') {
|
|
1022
|
+
encerrar();
|
|
1023
|
+
(acao.tipo === 'nova' ? criarSkill() : instalarSkill())
|
|
1024
|
+
.then(() => abrirMarketplace())
|
|
1025
|
+
.then(resolve);
|
|
1026
|
+
}
|
|
1027
|
+
};
|
|
1028
|
+
|
|
1029
|
+
/* Largar o teclado e devolver a caixa. Chamado por TODAS as saídas —
|
|
1030
|
+
o Esc, o "New Skill" e o "Instalar" —, porque o diálogo que vem
|
|
1031
|
+
depois usa o `ask`, e o `ask` precisa da caixa de volta. */
|
|
1032
|
+
const encerrar = () => {
|
|
1033
|
+
process.stdin.removeListener('keypress', aoTeclar);
|
|
1034
|
+
process.stdin.removeListener('end', aoAcabar);
|
|
1035
|
+
process.stdin.removeListener('close', aoAcabar);
|
|
1036
|
+
sliderAtivo = false;
|
|
1037
|
+
if (rl && rl.retomar) rl.retomar();
|
|
1038
|
+
};
|
|
1039
|
+
|
|
1040
|
+
/* A entrada pode acabar com a tela aberta (pipe que terminou, Ctrl+D,
|
|
1041
|
+
terminal fechado). Sem isto o programa ficaria esperando para
|
|
1042
|
+
sempre uma tecla que não vem mais — pendurado e calado, que é o
|
|
1043
|
+
pior jeito de travar. */
|
|
1044
|
+
const aoAcabar = () => { encerrar(); resolve(); };
|
|
1045
|
+
process.stdin.once('end', aoAcabar);
|
|
1046
|
+
process.stdin.once('close', aoAcabar);
|
|
1047
|
+
|
|
1048
|
+
sliderAtivo = true;
|
|
1049
|
+
if (rl && rl.suspender) rl.suspender();
|
|
1050
|
+
pintar(true);
|
|
1051
|
+
process.stdin.on('keypress', aoTeclar);
|
|
1052
|
+
});
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
/* ── New Skill: o nome, e depois o prompt ────────────────────────────────
|
|
1056
|
+
* Em sequência, como foi pedido. O conteúdo é multilinha e termina numa linha
|
|
1057
|
+
* com apenas `.` — não em Enter: o prompt de uma skill tem parágrafos, e
|
|
1058
|
+
* terminar no primeiro Enter tornaria impossível escrever uma skill de
|
|
1059
|
+
* verdade sem colar tudo numa linha só.
|
|
1060
|
+
*/
|
|
1061
|
+
async function criarSkill() {
|
|
1062
|
+
console.log('');
|
|
1063
|
+
console.log(' ' + c.bold(c.brand('New Skill')));
|
|
1064
|
+
console.log(' ' + c.muted('Uma skill é conhecimento em texto: o que o Primo deve saber'));
|
|
1065
|
+
console.log(' ' + c.muted('e seguir quando o assunto aparecer.'));
|
|
1066
|
+
console.log('');
|
|
1067
|
+
|
|
1068
|
+
const nome = String(await ask(' ' + c.brand('❯ ') + c.white('Nome da skill: '))).trim();
|
|
1069
|
+
if (!nome) { console.log(c.muted(' Sem nome, sem skill.')); return; }
|
|
1070
|
+
|
|
1071
|
+
console.log('');
|
|
1072
|
+
console.log(' ' + c.muted('Agora o conteúdo — o prompt inteiro dela.'));
|
|
1073
|
+
console.log(' ' + c.dim('Escreva quantas linhas quiser. Termine com um ponto sozinho numa linha.'));
|
|
1074
|
+
console.log('');
|
|
1075
|
+
|
|
1076
|
+
const linhas = [];
|
|
1077
|
+
for (;;) {
|
|
1078
|
+
const l = await ask(' ' + c.dim('│ '));
|
|
1079
|
+
if (String(l).trim() === '.') break;
|
|
1080
|
+
linhas.push(l);
|
|
1081
|
+
// Sem teto, um Enter preso na tecla viraria um arquivo de milhões de
|
|
1082
|
+
// linhas. 400 é muito mais do que qualquer skill precisa.
|
|
1083
|
+
if (linhas.length >= 400) { console.log(c.muted(' (chegou ao limite de linhas)')); break; }
|
|
1084
|
+
}
|
|
1085
|
+
const corpo = linhas.join('\n').trim();
|
|
1086
|
+
if (!corpo) { console.log(c.muted(' Sem conteúdo, sem skill.')); return; }
|
|
1087
|
+
|
|
1088
|
+
console.log('');
|
|
1089
|
+
const quando = String(await ask(' ' + c.brand('❯ ') + c.white('Quando usar? ')
|
|
1090
|
+
+ c.dim('(palavras separadas por vírgula) '))).trim();
|
|
1091
|
+
const descricao = String(await ask(' ' + c.brand('❯ ') + c.white('Uma linha do que ela faz: '))).trim();
|
|
1092
|
+
|
|
1093
|
+
const r = skills.criar(nome, corpo, { quando, descricao });
|
|
1094
|
+
if (!r.ok) { console.log(c.err(` ${r.error}`)); return; }
|
|
1095
|
+
console.log('');
|
|
1096
|
+
console.log(c.ok(` Skill cadastrada: ${r.nome}`) + c.muted(` (${shortPath(r.caminho)})`));
|
|
1097
|
+
if (!quando) {
|
|
1098
|
+
// Sem gatilho ela nunca entra sozinha num pedido. Dizer isso agora
|
|
1099
|
+
// evita a conclusão de que "a skill não funciona".
|
|
1100
|
+
console.log(c.warn(' Sem palavras em "quando usar", ela não vai entrar sozinha nos pedidos.'));
|
|
1101
|
+
console.log(c.dim(' Edite o arquivo e preencha o campo `quando:` quando quiser.'));
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
async function instalarSkill() {
|
|
1106
|
+
console.log('');
|
|
1107
|
+
const caminho = String(await ask(' ' + c.brand('❯ ') + c.white('Caminho do SKILL.md: '))).trim();
|
|
1108
|
+
if (!caminho) return;
|
|
1109
|
+
const r = await instalarComPortao(caminho);
|
|
1110
|
+
console.log(r.ok ? c.ok(` Skill instalada: ${r.nome}`) : c.err(` ${r.error}`));
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
/* Instala passando pelo portão (lib/skill/portao-skill.js). Achou algo: mostra cada
|
|
1114
|
+
achado com arquivo:linha e faz a mesma pergunta do que não tem volta
|
|
1115
|
+
(autorizarControle) — Enter sozinho é NÃO. */
|
|
1116
|
+
async function instalarComPortao(caminho) {
|
|
1117
|
+
const r = skills.instalarDe(caminho);
|
|
1118
|
+
if (!r.bloqueada) return r;
|
|
1119
|
+
console.log('');
|
|
1120
|
+
console.log(' ' + c.err(r.error));
|
|
1121
|
+
for (const linha of portaoSkill.descrever(r.achados).slice(0, 20)) console.log(' ' + c.warn(linha));
|
|
1122
|
+
if (r.achados.length > 20) console.log(c.dim(` … e mais ${r.achados.length - 20}`));
|
|
1123
|
+
console.log(' ' + c.dim('Leia cada linha: o portão acha padrão, não intenção.'));
|
|
1124
|
+
const resposta = await autorizarControle(`instalar a skill de ${caminho} mesmo assim`, { tipo: 'perigo' });
|
|
1125
|
+
if (resposta !== 'agora' && resposta !== 'sessao') return { ok: false, error: 'Skill não instalada.' };
|
|
1126
|
+
return skills.instalarDe(caminho, { forcar: true });
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
async function sendPrompt(userText, { digitado = false } = {}) {
|
|
1130
|
+
/* O portão do plano. Sem ele o bloqueio da abertura seria só um texto na
|
|
1131
|
+
tela: a pessoa leria "você não tem acesso" e mandaria a primeira coisa
|
|
1132
|
+
do mesmo jeito, e funcionaria.
|
|
1133
|
+
|
|
1134
|
+
De cortesia, não de segurança — este arquivo vai publicado no npm com o
|
|
1135
|
+
código à vista, e a checagem é uma linha que qualquer um apaga. Quem
|
|
1136
|
+
segura de verdade é o primocode-server. O que ele faz aqui é dizer o
|
|
1137
|
+
que houve e como resolver, em vez de deixar a pessoa achando que o
|
|
1138
|
+
produto está quebrado. */
|
|
1139
|
+
if (state.liberado === false) {
|
|
1140
|
+
console.log(c.err(' O PrimoCode pede um plano (a partir de R$ 69,90/mês).'));
|
|
1141
|
+
console.log(c.muted(' Veja e assine com ') + c.brand('/account plans')
|
|
1142
|
+
+ c.muted(' · já assinou? ') + c.brand('/account'));
|
|
1143
|
+
return;
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
/* Pedido grande: uma linha dizendo quanto deve gastar do plano de hoje (lib/config/limite.js). Sem o limite do plano,
|
|
1147
|
+
diz isso com todas as letras (uma vez por conversa) em vez de inventar %. Só pra quem digitou, no terminal. */
|
|
1148
|
+
if (digitado && !state.semTerminal && process.stdin.isTTY) {
|
|
1149
|
+
try {
|
|
1150
|
+
const L = require('../config/limite.js');
|
|
1151
|
+
const anexos = state.attachedFiles.reduce((n, f) => n + String(f.content || '').length, 0);
|
|
1152
|
+
const limite = L.limiteConhecido();
|
|
1153
|
+
if (L.pedidoGrande(userText, anexos) && (limite || !state.avisouSemLimite)) {
|
|
1154
|
+
const { total } = extra.resumoCusto(contadorDaSessao);
|
|
1155
|
+
const media = total.pedidos ? Math.round((total.enviados + total.recebidos) / total.pedidos) : 0;
|
|
1156
|
+
console.log(c.muted(' ' + L.linhaDoPedido({ tokens: L.estimar({ texto: userText, anexosChars: anexos, mediaPorPedido: media }), limite, usadoHoje: L.usoDeHoje().tokens })));
|
|
1157
|
+
if (!limite) state.avisouSemLimite = true;
|
|
1158
|
+
}
|
|
1159
|
+
} catch { /* a estimativa nunca derruba o pedido */ }
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
// PRIMOCODE_TEMPOS=1: uma linha no fim com o custo de cada fase.
|
|
1163
|
+
tempos.comecar();
|
|
1164
|
+
const inicio = Date.now();
|
|
1165
|
+
/* Pedido em lista, com 4 itens ou mais (lib/partes.js): PERGUNTA se faz um de cada vez. Só no terminal de
|
|
1166
|
+
verdade; no app e no -p, segue inteiro como sempre. */
|
|
1167
|
+
// só o que a PESSOA digitou: o pedido que o próprio PrimoCode monta (o conserto do /conferir leva a saída do teste,
|
|
1168
|
+
// e o mocha escreve "1) nome do teste") não pode virar "esse pedido tem 4 partes" (achado da revisão de 24/10)
|
|
1169
|
+
const divisao = digitado && !state.semTerminal && process.stdin.isTTY ? require('../partes.js').dividir(userText) : null;
|
|
1170
|
+
if (divisao && await confirm(`Esse pedido tem ${divisao.partes.length} partes. De uma vez só, pedido grande costuma travar no meio. Faço uma de cada vez, conferindo entre elas?`)) {
|
|
1171
|
+
const P = require('../partes.js');
|
|
1172
|
+
try {
|
|
1173
|
+
for (let i = 0; i < divisao.partes.length; i++) {
|
|
1174
|
+
console.log(c.brand(`\n ▸ parte ${i + 1} de ${divisao.partes.length}: `) + c.white(divisao.partes[i].slice(0, 80)));
|
|
1175
|
+
await enviarPedido(P.pedidoDaParte(divisao, i));
|
|
1176
|
+
if (require('../session/runner/act.js').interrompido()) break; // Esc Esc numa parte para as que faltam
|
|
1177
|
+
}
|
|
1178
|
+
} finally {
|
|
1179
|
+
const linha = tempos.relatorio();
|
|
1180
|
+
if (linha) console.log(c.dim(` ⏱ ${linha}`));
|
|
1181
|
+
}
|
|
1182
|
+
return;
|
|
1183
|
+
}
|
|
1184
|
+
try { await enviarPedido(userText); }
|
|
1185
|
+
finally {
|
|
1186
|
+
const linha = tempos.relatorio();
|
|
1187
|
+
if (linha) console.log(c.dim(` ⏱ ${linha}`));
|
|
1188
|
+
/* O fecho de cada resposta, como no OpenCode ("▣ Build · Nemotron ·
|
|
1189
|
+
4.0s"): quem respondeu, com que esforço, e quanto levou. */
|
|
1190
|
+
const m = state.mode === 'auto' ? (state.modoEfetivo || 'auto') : state.mode;
|
|
1191
|
+
if (!state.semTerminal) {
|
|
1192
|
+
console.log('\n ' + `${COR_MODO[m] || COR_MODO.auto}▣${c.reset} ` + c.white(NOME_MODO[m] || m)
|
|
1193
|
+
+ c.dim(` · ${effort.normalizar(state.config.effort)} · ${((Date.now() - inicio) / 1000).toFixed(1)}s`) + '\n');
|
|
1194
|
+
// O que o agente deixou de pé (run_background), com o endereço pra abrir.
|
|
1195
|
+
const rodape = require('../fundo.js').linhasRodape(require('../fundo.js').listar(), c);
|
|
1196
|
+
if (rodape.length) console.log(rodape.join('\n') + '\n');
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
/* Marca no arquivo de hoje o que ESTA conversa já gastou (lib/config/limite.js): é o que o /usage soma. */
|
|
1202
|
+
const IDENTIDADE_DA_SESSAO = `${process.pid}-${Date.now()}`;
|
|
1203
|
+
/* Tarefa em segundo plano que acabou sozinha: uma linha na tela (o modelo recebe o aviso na próxima volta). */
|
|
1204
|
+
require('../fundo.js').aoTerminar((a) => {
|
|
1205
|
+
if (state.semTerminal) return;
|
|
1206
|
+
process.stdout.write('\n ' + (a.ok ? c.ok('✔') : c.err('✘')) + ' ' + c.muted(`tarefa ${a.id} terminou (código ${a.codigo}): ${a.comando.slice(0, 60)}`) + '\n');
|
|
1207
|
+
});
|
|
1208
|
+
function guardarUsoDeHoje() {
|
|
1209
|
+
try {
|
|
1210
|
+
const { total } = extra.resumoCusto(contadorDaSessao);
|
|
1211
|
+
require('../config/limite.js').guardarSessao(IDENTIDADE_DA_SESSAO, total.enviados + total.recebidos);
|
|
1212
|
+
} catch { /* contar nunca derruba um pedido */ }
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
async function enviarPedido(userText) {
|
|
1216
|
+
let prompt = userText;
|
|
1217
|
+
const custoAntes = extra.resumoCusto(contadorDaSessao); // pro "Este pedido: …" do fim
|
|
1218
|
+
// "@index.html" no pedido é um /attach só deste pedido: vai junto dos
|
|
1219
|
+
// anexos, mas não fica em state.attachedFiles para o próximo.
|
|
1220
|
+
const citados = mencoesDoPedido(userText);
|
|
1221
|
+
// "@https://…" no pedido é um /web só deste pedido (lib/web-pagina.js)
|
|
1222
|
+
const W = require('../web-pagina.js');
|
|
1223
|
+
for (const url of W.urlsDoPedido(userText)) {
|
|
1224
|
+
const r = await W.baixar(url);
|
|
1225
|
+
if (r.ok) {
|
|
1226
|
+
citados.push({ path: r.url, content: (r.titulo ? `# ${r.titulo}\n\n` : '') + r.texto });
|
|
1227
|
+
console.log(c.dim(` ⎿ anexado: ${r.titulo || r.url} (${r.palavras} palavras${r.cortado ? ', o começo da página' : ''})`));
|
|
1228
|
+
} else console.log(c.dim(` ⎿ não anexei ${url}: ${r.error}`));
|
|
1229
|
+
}
|
|
1230
|
+
const anexos = [...state.attachedFiles, ...citados];
|
|
1231
|
+
if (anexos.length) {
|
|
1232
|
+
const parts = anexos.map((f) => `Arquivo: ${f.path}\n\`\`\`\n${f.content}\n\`\`\``);
|
|
1233
|
+
prompt = parts.join('\n\n') + '\n\n' + userText;
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
// O modo primocode manda o schema das 30 tools em todo pedido (~4.700
|
|
1237
|
+
// tokens). No auto, quem não vai usar ferramenta não paga por ela.
|
|
1238
|
+
let modo = state.mode;
|
|
1239
|
+
if (modo === 'auto') {
|
|
1240
|
+
// O modo do pedido ANTERIOR entra na decisão: no meio de uma tarefa,
|
|
1241
|
+
// "refaz" e "agora põe música" são continuação, não papo novo.
|
|
1242
|
+
const escolha = escolherModo(userText, { ultimoModo: state.modoEfetivo });
|
|
1243
|
+
modo = escolha.modo;
|
|
1244
|
+
state.modoEfetivo = modo;
|
|
1245
|
+
const rotulo = modo === 'primocode' ? c.warn('Primo Code') : c.brandDim('Chat');
|
|
1246
|
+
console.log(c.dim(` ⎿ ${ui.stripAnsi(rotulo)} · ${escolha.motivo}`));
|
|
1247
|
+
refreshPrompt();
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
if (modo === 'primocode') {
|
|
1251
|
+
// "baixa o vídeo" / "exporta em mp4" não precisa de IA NENHUMA: é
|
|
1252
|
+
// abrir a última criação do Studio com #gravar — o navegador pede a
|
|
1253
|
+
// permissão de tela (a aprovação), grava a passada e baixa no fim.
|
|
1254
|
+
// Antes isso virava uma tarefa inteira de modelo (id inventado,
|
|
1255
|
+
// mídia inventada, limite estourado) para chegar no mesmo lugar.
|
|
1256
|
+
if (await baixarCriacaoDireto(userText)) { refreshPrompt(); return; }
|
|
1257
|
+
|
|
1258
|
+
const plan = await prepararPasta(userText);
|
|
1259
|
+
|
|
1260
|
+
// O Chrome só aparece na tela quando o pedido é de navegador (lib/browser.js, definirVisivel).
|
|
1261
|
+
require('../browser.js').definirVisivel(querNavegador(userText));
|
|
1262
|
+
|
|
1263
|
+
/* AS REFERÊNCIAS DO VÍDEO (lib/plugin/estudio/referencias.js) saem do próprio
|
|
1264
|
+
pedido. O padrão é SEM IMAGEM, e o menu 1/2/3 saiu: "por padrão, NÃO
|
|
1265
|
+
usar imagens; somente quando o usuário pedir explicitamente" (07/10). */
|
|
1266
|
+
const referencias = require('../plugin/estudio/referencias.js');
|
|
1267
|
+
referencias.limpar();
|
|
1268
|
+
const producao = require('../plugin/estudio/diretor.js').precisaDeProducao(userText);
|
|
1269
|
+
if (producao.producao && producao.formato === 'video') {
|
|
1270
|
+
const r = referencias.inferir(userText);
|
|
1271
|
+
referencias.definir(r.modo, r.escopo, r.explicito);
|
|
1272
|
+
console.log(c.dim(` ⎿ imagens: ${{ aberto: 'sim, da web', fechado: 'só de ' + r.escopo, sem: r.explicito ? 'nenhuma, só motion' : 'nenhuma (o padrão)' }[r.modo]}`)
|
|
1273
|
+
+ (r.modo === 'sem' && !r.explicito ? c.dim(' · diga "adicione imagens de apoio" para usar') : ''));
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
// O resumo da rodada anterior é feito em segundo plano logo depois
|
|
1277
|
+
// dela; aqui só se espera ele terminar, para não sair com memória velha.
|
|
1278
|
+
//
|
|
1279
|
+
// O pedido passa por uma cabeça antes de virar trabalho: conserta o
|
|
1280
|
+
// que está torto, diz qual é o entregável e o que conta como pronto.
|
|
1281
|
+
// UMA chamada faz as duas coisas: arruma o pedido torto e, se fizer
|
|
1282
|
+
// sentido, divide em passos. Eram duas idas ao modelo por pedido, e
|
|
1283
|
+
// num plano limitado por REQUISIÇÕES (o grátis da Groq são 30 por
|
|
1284
|
+
// minuto) cada chamada extra custa tanto quanto token.
|
|
1285
|
+
//
|
|
1286
|
+
// As duas esperas correm JUNTAS. Uma não lê o que a outra escreve: o
|
|
1287
|
+
// plano só olha o texto do pedido, e o resumo só a conversa de antes.
|
|
1288
|
+
// Em fila, o pedido de duas fases pagava o resumo e DEPOIS o plano —
|
|
1289
|
+
// duas idas ao modelo em série antes da primeira rodada.
|
|
1290
|
+
const [, passos] = await Promise.all([
|
|
1291
|
+
tempos.medir('espera do resumo', () => esperarResumo()),
|
|
1292
|
+
tempos.medir('plano', () => dividirTarefa(prompt)),
|
|
1293
|
+
]);
|
|
1294
|
+
|
|
1295
|
+
let r = null;
|
|
1296
|
+
let jaFeito = '';
|
|
1297
|
+
/* O livro do PEDIDO, não do passo. Um plano de três passos são três
|
|
1298
|
+
chamadas de runAct, cada uma com o seu registro — e o balanço que
|
|
1299
|
+
interessa é o do pedido inteiro: quem pediu um vídeo não quer três
|
|
1300
|
+
balanços, quer saber o que existe no disco quando ele terminar. */
|
|
1301
|
+
const livro = registro.novo();
|
|
1302
|
+
// Um checkpoint por PEDIDO (não por passo): é o que o /desfazer volta.
|
|
1303
|
+
// Com a pasta: a foto do projeto inteiro sai AGORA, antes de qualquer
|
|
1304
|
+
// tool — é ela que dá volta ao `rm`/`mv` que o run_shell fizer.
|
|
1305
|
+
checkpoint.iniciar(userText, projectDir());
|
|
1306
|
+
for (let i = 0; i < passos.length; i++) {
|
|
1307
|
+
if (i > 0) console.log(c.dim(` ⎿ ${passos[i].titulo}`));
|
|
1308
|
+
// Só fato de passo CONCLUÍDO entra aqui. Num pedido real o passo de
|
|
1309
|
+
// pesquisa morreu e o texto "Parei sem concluir..." foi injetado
|
|
1310
|
+
// como "use estes fatos" — e o passo seguinte obedeceu: criou o
|
|
1311
|
+
// vídeo sem fato nenhum, proibido de pesquisar.
|
|
1312
|
+
const contexto = !jaFeito ? ''
|
|
1313
|
+
: `\n\nO QUE JÁ FOI FEITO ANTES (use estes fatos, não pesquise de novo):\n${jaFeito}`;
|
|
1314
|
+
const semFatos = i > 0 && !jaFeito
|
|
1315
|
+
? '\n\nATENÇÃO: o passo anterior não trouxe fatos. Trabalhe só com o que está no pedido. '
|
|
1316
|
+
+ 'É PROIBIDO inventar dado de empresa, data, preço ou pessoa — na dúvida, não afirme.'
|
|
1317
|
+
: '';
|
|
1318
|
+
// o pedido citou arquivo: o agente sabe antes, não só no aviso do fim (lib/escopo.js)
|
|
1319
|
+
const pedido = passos[i].pedido + contexto + semFatos + require('../escopo.js').nota(userText);
|
|
1320
|
+
|
|
1321
|
+
const rodarPasso = (texto = pedido) => runAct(texto, {
|
|
1322
|
+
server: state.config.server,
|
|
1323
|
+
model: state.config.model,
|
|
1324
|
+
effort: state.config.effort,
|
|
1325
|
+
token: state.config.token,
|
|
1326
|
+
// Só o primeiro passo enxerga a conversa: os seguintes recebem o
|
|
1327
|
+
// que interessa em `jaFeito`, e conversa a mais só ocupa o teto.
|
|
1328
|
+
history: i === 0 ? memoria.paraEnviar(state.memoria, state.history, contextoDoProjeto()) : [],
|
|
1329
|
+
projectDir: plan.dir,
|
|
1330
|
+
projectName: plan.name || state.currentProject,
|
|
1331
|
+
// Só chamado se o agente for mesmo MEXER EM ARQUIVO — abrir o Chrome
|
|
1332
|
+
// não é motivo para criar pasta de projeto.
|
|
1333
|
+
ensureWorkDir: plan.pending ? () => createPendingProject(plan) : null,
|
|
1334
|
+
// O portão do computador: quem pergunta é o terminal, quem
|
|
1335
|
+
// lembra da resposta é a sessão.
|
|
1336
|
+
// No pedido único (`primo "…"`) não há ninguém para responder:
|
|
1337
|
+
// sem `autorizar`, o que pede licença é recusado (lib/permission/perigo.js).
|
|
1338
|
+
autorizar: state.semTerminal ? undefined : autorizarControle,
|
|
1339
|
+
escolher: state.semTerminal ? undefined : (q, o, op) => {
|
|
1340
|
+
const PQ = require('../tool/perguntar');
|
|
1341
|
+
if (process.stdin.isTTY && process.stdout.isTTY) {
|
|
1342
|
+
return PQ.escolherComSetas({ stdin: process.stdin, stdout: process.stdout, suspender: () => rl && rl.suspender && rl.suspender(), retomar: () => rl && rl.retomar && rl.retomar() }, c, q, o, { ...op, ask });
|
|
1343
|
+
}
|
|
1344
|
+
return PQ.escolherNoTerminal(ask, c, q, o, op);
|
|
1345
|
+
},
|
|
1346
|
+
// A memória do AGENTS.md só vai se o resumo ainda não a carrega.
|
|
1347
|
+
memoriaDaPasta: !memoria.jaDobrou(state.memoria, plan.dir),
|
|
1348
|
+
mudarPasta: state.semTerminal ? null : mudarPastaPeloAgente,
|
|
1349
|
+
controle: state.controle,
|
|
1350
|
+
permissoes: state.config.permissoes,
|
|
1351
|
+
// Pedido de mexer no computador leva a dica que libera as
|
|
1352
|
+
// ferramentas desktop_* no servidor (ver DICA_COMPUTADOR).
|
|
1353
|
+
instrucao: [i === 0 && querComputador(userText) ? vozModo.DICA_COMPUTADOR : '',
|
|
1354
|
+
i === 0 ? require('../plugin/estudio/referencias.js').instrucao() : '',
|
|
1355
|
+
// As imagens do pedido (arrastadas ou coladas): guardadas para o Estúdio importar, e ditas ao agente.
|
|
1356
|
+
i === 0 ? (() => { const R = require('../plugin/estudio/referencias.js'); return R.instrucaoDasImagens(R.guardarImagens(R.imagensNoTexto(userText))); })() : '',
|
|
1357
|
+
i === 0 ? plan.notaOutraPasta || '' : ''].filter(Boolean).join('\n\n'),
|
|
1358
|
+
});
|
|
1359
|
+
|
|
1360
|
+
r = await rodarPasso();
|
|
1361
|
+
// O mudar_pasta trocou no meio: os passos seguintes seguem lá.
|
|
1362
|
+
if (r && r.pasta && path.resolve(r.pasta) !== path.resolve(plan.dir)) { plan.dir = r.pasta; plan.pending = false; }
|
|
1363
|
+
if (r && r.estudio) state.estudioAtivo = r.estudio;
|
|
1364
|
+
/* Passo que parou no meio NÃO devolve a tarefa para a pessoa
|
|
1365
|
+
dividir. Se ele já tinha feito alguma coisa (arquivo, comando),
|
|
1366
|
+
o próprio CLI pede a continuação — com a lista do que já existe
|
|
1367
|
+
no disco, para não refazer. Até CONTINUACOES vezes, e só
|
|
1368
|
+
enquanto cada volta produz algo: continuação que não mexe em
|
|
1369
|
+
nada é laço, e laço para.
|
|
1370
|
+
Num plano de vários passos, o passo que desistiu sem fazer nada
|
|
1371
|
+
ganha UMA segunda chance — costuma ser tropeço transitório do
|
|
1372
|
+
modelo grátis. Falhou de novo: o
|
|
1373
|
+
plano segue com o aviso de "sem fatos", nunca com o texto da
|
|
1374
|
+
falha fantasiado de resultado. */
|
|
1375
|
+
let continuacoes = 0;
|
|
1376
|
+
let tentouDeNovo = false;
|
|
1377
|
+
while (!r.parado && r.concluiu === false) {
|
|
1378
|
+
registro.juntar(livro, r.registro);
|
|
1379
|
+
// Sem registro é erro do provedor (cota, rede): retomar só bate
|
|
1380
|
+
// no mesmo muro.
|
|
1381
|
+
if (r.registro && !registro.vazio(r.registro) && continuacoes < CONTINUACOES) {
|
|
1382
|
+
continuacoes++;
|
|
1383
|
+
console.log(c.dim(' ⎿ continuando de onde parou'));
|
|
1384
|
+
r = await rodarPasso(pedidoDeContinuacao(passos[i].pedido, livro));
|
|
1385
|
+
continue;
|
|
1386
|
+
}
|
|
1387
|
+
if (!tentouDeNovo && passos.length > 1 && registro.vazio(r.registro) && continuacoes === 0) {
|
|
1388
|
+
tentouDeNovo = true;
|
|
1389
|
+
console.log(c.dim(' ⎿ o passo não concluiu — tentando de novo'));
|
|
1390
|
+
r = await rodarPasso();
|
|
1391
|
+
continue;
|
|
1392
|
+
}
|
|
1393
|
+
break;
|
|
1394
|
+
}
|
|
1395
|
+
if (r.concluiu !== false || r.parado) registro.juntar(livro, r.registro);
|
|
1396
|
+
jaFeito = (r.concluiu !== false)
|
|
1397
|
+
? String((r.assistantMessage && r.assistantMessage.content) || '').slice(0, 1200)
|
|
1398
|
+
: '';
|
|
1399
|
+
if (r.parado) break; // Esc Esc no meio do plano para o plano inteiro
|
|
1400
|
+
}
|
|
1401
|
+
checkpoint.encerrar();
|
|
1402
|
+
|
|
1403
|
+
// O pedido nomeou arquivo e o agente mexeu em outros? Diz quais, e o /desfazer fora volta só esses (lib/escopo.js).
|
|
1404
|
+
try {
|
|
1405
|
+
const escopo = require('../escopo.js');
|
|
1406
|
+
const ultimo = checkpoint.lista(projectDir())[0];
|
|
1407
|
+
if (ultimo && ultimo.pedido === String(userText).replace(/\s+/g, ' ').trim()) {
|
|
1408
|
+
const fora = escopo.foraDoPedido(userText, ultimo.mudou, projectDir());
|
|
1409
|
+
if (fora.length) {
|
|
1410
|
+
escopo.texto(escopo.citados(userText), fora).forEach((l, i, ls) => console.log(i === 0 ? c.warn(' ' + l) : i === ls.length - 1 ? c.muted(' ' + l) : c.white(' ' + l)));
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
} catch { /* o aviso nunca derruba o pedido */ }
|
|
1414
|
+
// "nunca mexa no logo" dito no pedido: oferece guardar como regra, não guarda sozinho (lib/regras.js)
|
|
1415
|
+
try {
|
|
1416
|
+
const regras = require('../regras.js');
|
|
1417
|
+
const sug = regras.sugerir(userText, regras.ler(projectDir()));
|
|
1418
|
+
if (sug) console.log(c.muted(' Isso vale sempre? ') + c.white(`/rule ${sug}`) + c.muted(' (fica no PRIMO.md e não some quando a conversa é resumida)'));
|
|
1419
|
+
} catch { /* a oferta nunca derruba o pedido */ }
|
|
1420
|
+
|
|
1421
|
+
/* O balanço, depois da resposta. Depois, e não antes, de propósito: o
|
|
1422
|
+
que a pessoa quer ler primeiro é o que ele TEM A DIZER; a lista de
|
|
1423
|
+
arquivos é a conferência, e conferência se lê por último. */
|
|
1424
|
+
const balanco = registro.resumo(livro, { colunas: process.stdout.columns || 80 });
|
|
1425
|
+
if (balanco) console.log(balanco);
|
|
1426
|
+
const custo = extra.custoDoPedido(custoAntes, extra.resumoCusto(contadorDaSessao));
|
|
1427
|
+
if (custo) console.log(c.dim(` ${custo}`));
|
|
1428
|
+
guardarUsoDeHoje();
|
|
1429
|
+
// O rostinho do mascote, por último e numa linha só. O humor sai do
|
|
1430
|
+
// que aconteceu, não de adivinhar pelo texto da resposta.
|
|
1431
|
+
if (state.config.reacoes !== false && r) {
|
|
1432
|
+
const humor = r.parado ? 'parado' : r.concluiu === false ? 'preocupado' : 'feliz';
|
|
1433
|
+
console.log(ui.reacao(state.config.mascot, humor));
|
|
1434
|
+
}
|
|
1435
|
+
state.history.push({ role: 'user', content: userText });
|
|
1436
|
+
// na memória da conversa vai também o que o pedido fez no disco (arquivos, último teste): o pedido seguinte sabe
|
|
1437
|
+
let feito = '';
|
|
1438
|
+
try { feito = require('../registro.js').paraMemoria(r.registro); } catch { /* sem registro */ }
|
|
1439
|
+
state.history.push({ role: 'assistant', content: r.assistantMessage.content + (feito ? `\n\n${feito}` : '') });
|
|
1440
|
+
resumirDepois();
|
|
1441
|
+
state.lastResponse = r.assistantMessage.content;
|
|
1442
|
+
cfg.appendHistory({ mode: 'primocode', project: state.currentProject, prompt: userText });
|
|
1443
|
+
// Sobe cifrado, atrás, sem segurar o prompt. Se não houver conta ou
|
|
1444
|
+
// rede, não acontece nada — a conversa segue aqui do mesmo jeito.
|
|
1445
|
+
state.gravador.turno(userText, r.assistantMessage.content,
|
|
1446
|
+
{ modo: 'primocode', projeto: state.currentProject || null });
|
|
1447
|
+
// O parceiro do /team revisa o que mudou (lib/team.js). Depois do histórico: o conserto vem como pedido seguinte.
|
|
1448
|
+
await revisaoDoParceiro(userText, livro, r);
|
|
1449
|
+
} else {
|
|
1450
|
+
await tempos.medir('espera do resumo', () => esperarResumo());
|
|
1451
|
+
await tempos.medir('chat', () => runChat(prompt, userText));
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
state.attachedFiles = [];
|
|
1455
|
+
refreshPrompt();
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
/* "UM FAZ, O OUTRO REVISA" (/team). O PrimoCode fez; o parceiro lê a mudança
|
|
1459
|
+
(só lendo, na pasta do projeto, com prazo) e devolve a revisão. Achou
|
|
1460
|
+
problema, a pessoa diz se corrige; o conserto não é revisado de novo. */
|
|
1461
|
+
async function revisaoDoParceiro(userText, livro, r) {
|
|
1462
|
+
const nome = state.config.team;
|
|
1463
|
+
if (!nome || state.consertandoRevisao || !r || r.parado || !livro) return;
|
|
1464
|
+
const arquivos = [...(livro.criados || []), ...(livro.alterados || [])];
|
|
1465
|
+
if (!arquivos.length) return;
|
|
1466
|
+
const team = require('../team.js');
|
|
1467
|
+
const dele = team.instalados().find((x) => x.nome === nome);
|
|
1468
|
+
if (!dele) { console.log(c.warn(` O ${nome} não está mais instalado: sem revisão. /team mostra os que você tem.`)); return; }
|
|
1469
|
+
const dir = r.pasta || projectDir();
|
|
1470
|
+
const diff = team.diffDaVez(dir, arquivos);
|
|
1471
|
+
if (!diff) return;
|
|
1472
|
+
console.log(c.muted(` ${dele.titulo} revisando o que eu fiz (só lendo)…`));
|
|
1473
|
+
const rev = await team.rodar(nome, 'revisar', { prompt: team.pedidoDeRevisao({ pedido: userText, diff }), dir, caminho: dele.caminho,
|
|
1474
|
+
linha: (l) => console.log(c.dim(` ${nome} │ ${l}`)) });
|
|
1475
|
+
if (!rev.ok) { console.log(c.warn(` ${rev.erro}`)); return; }
|
|
1476
|
+
if (!rev.texto || team.semProblema(rev.texto)) { console.log(c.ok(` ✓ ${nome} revisou: nada a corrigir.`)); return; }
|
|
1477
|
+
console.log(c.white(` A revisão do ${nome}:`));
|
|
1478
|
+
for (const l of rev.texto.split('\n')) console.log(` ${l}`);
|
|
1479
|
+
if (state.semTerminal) return;
|
|
1480
|
+
if (!(await confirm('Corrijo o que a revisão achou?'))) return;
|
|
1481
|
+
state.consertandoRevisao = true;
|
|
1482
|
+
try { await sendPrompt(team.pedidoDeConserto(nome, rev.texto)); } finally { state.consertandoRevisao = false; }
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
/* `/team <nome> faz <pedido>`: o parceiro faz numa cópia do projeto (git
|
|
1486
|
+
worktree, ou cópia da pasta), o PrimoCode mostra o que mudou, passa cada
|
|
1487
|
+
arquivo pelo portão (lib/permission/perigo.js) e só aplica com o sim. /undo volta. */
|
|
1488
|
+
async function parceiroFaz(nome, pedido) {
|
|
1489
|
+
const team = require('../team.js');
|
|
1490
|
+
const dele = team.instalados().find((x) => x.nome === nome);
|
|
1491
|
+
const dir = projectDir();
|
|
1492
|
+
if (!pastaSegura(dir) || path.resolve(dir) === path.resolve(cfg.ROOT_DIR)) {
|
|
1493
|
+
console.log(c.warn(' Entre num projeto antes (/projects ou /dir): o parceiro trabalha numa cópia dele.'));
|
|
1494
|
+
return;
|
|
1495
|
+
}
|
|
1496
|
+
let copia;
|
|
1497
|
+
try { copia = team.prepararCopia(dir); } catch (e) { console.log(c.warn(` Não consegui preparar a cópia do projeto: ${String(e.message || e).split('\n')[0]}`)); return; }
|
|
1498
|
+
try {
|
|
1499
|
+
console.log(c.muted(` ${dele.titulo} trabalhando numa cópia do projeto${copia.git ? ' (git worktree)' : ''}…`));
|
|
1500
|
+
const r = await team.rodar(nome, 'fazer', { prompt: team.pedidoDeFazer(pedido), dir: copia.pasta, caminho: dele.caminho,
|
|
1501
|
+
linha: (l) => console.log(c.dim(` ${nome} │ ${l}`)) });
|
|
1502
|
+
if (!r.ok) { console.log(c.warn(` ${r.erro}`)); return; }
|
|
1503
|
+
if (r.texto) { console.log(c.white(` O ${nome} disse:`)); for (const l of r.texto.split('\n')) console.log(` ${l}`); }
|
|
1504
|
+
const m = team.mudancasDaCopia(copia);
|
|
1505
|
+
if (!m.arquivos.length) { console.log(c.muted(' Ele não mudou nenhum arquivo. O projeto ficou como estava.')); return; }
|
|
1506
|
+
console.log(c.white(` O que ele mudou (${m.arquivos.length} arquivo${m.arquivos.length > 1 ? 's' : ''}):`));
|
|
1507
|
+
const linhas = m.patch.split('\n');
|
|
1508
|
+
for (const l of linhas.slice(0, 200)) console.log(' ' + (/^\+(?!\+\+)/.test(l) ? c.ok(l) : /^-(?!--)/.test(l) ? c.err(l) : c.dim(l)));
|
|
1509
|
+
if (linhas.length > 200) console.log(c.dim(` … e mais ${linhas.length - 200} linhas`));
|
|
1510
|
+
if (!state.controle.perigo) state.controle.perigo = perigo.novo();
|
|
1511
|
+
const recusas = await team.passarPeloPortao(m.arquivos, { projectDir: dir, aplicarEm: copia.aplicarEm, modo: state.config.permissoes,
|
|
1512
|
+
estado: state.controle.perigo, perguntar: state.semTerminal ? undefined : autorizarControle });
|
|
1513
|
+
if (recusas.length) { console.log(c.warn(` O portão do PrimoCode recusou: ${recusas.join('; ')}. Nada foi aplicado.`)); return; }
|
|
1514
|
+
if (state.semTerminal) { console.log(c.muted(' No modo script eu não aplico sozinho: rode no terminal do PrimoCode pra aplicar.')); return; }
|
|
1515
|
+
if (!(await confirm('Aplico essa mudança no projeto?'))) { console.log(c.muted(' Não apliquei. O projeto ficou como estava.')); return; }
|
|
1516
|
+
checkpoint.iniciar(`/team ${nome} faz ${pedido}`, dir);
|
|
1517
|
+
for (const a of m.arquivos) checkpoint.antesDeMudar(path.join(copia.aplicarEm, a.caminho), dir);
|
|
1518
|
+
const ap = team.aplicar(copia, m.patch);
|
|
1519
|
+
checkpoint.encerrar();
|
|
1520
|
+
console.log(ap.ok ? c.ok(` ✓ Apliquei. /undo volta.`) : c.warn(` ${ap.erro}`));
|
|
1521
|
+
} finally { copia.limpar(); }
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
/**
|
|
1525
|
+
* Arruma o pedido e divide em passos — as duas coisas, ESCONDIDAS.
|
|
1526
|
+
*
|
|
1527
|
+
* ARRUMAR: gente pede curto e torto ("cria um vidro anunciando o founders
|
|
1528
|
+
* ai"). Sem isso o agente adivinha, e adivinha errado. É oculto porque
|
|
1529
|
+
* encanamento não é conversa: o usuário quer ver a coisa acontecendo, não um
|
|
1530
|
+
* relatório do que a máquina entendeu — e não há o que aprovar, já que o
|
|
1531
|
+
* refino não decide nada, só desambigua o que ele já disse.
|
|
1532
|
+
*
|
|
1533
|
+
* DIVIDIR: o motivo é aritmético. Com 6.000 tokens por minuto, "pesquise
|
|
1534
|
+
* sobre a X e crie um vídeo" não cabe numa conversa só — custo fixo ~3.700,
|
|
1535
|
+
* spec do formato ~1.400, fatos da pesquisa o resto, e sobram 512 para o
|
|
1536
|
+
* agente escrever. Em dois pedidos cada um cabe folgado, porque cada um leva
|
|
1537
|
+
* só as ferramentas e o prompt do seu passo.
|
|
1538
|
+
*
|
|
1539
|
+
* As duas numa chamada só: elas leem o mesmo texto, e num plano limitado por
|
|
1540
|
+
* requisições por minuto a segunda ida ao modelo custa tanto quanto token.
|
|
1541
|
+
*
|
|
1542
|
+
* Falhou? O pedido do usuário, inteiro, como ele escreveu.
|
|
1543
|
+
*/
|
|
1544
|
+
// A ÚNICA divisão que compensa: DESCOBRIR uma coisa e CRIAR outra com ela.
|
|
1545
|
+
// O resto é pedido de uma fase só, e mandar para o planejador era pagar uma
|
|
1546
|
+
// chamada de API para ouvir "não divida" — quando o modelo não resolvia
|
|
1547
|
+
// inventar passos que ninguém pediu, que era o "faz coisas nada a ver".
|
|
1548
|
+
const RE_DESCOBRIR = /\b(pesquis|busca|procur|descubr|investig|analis|leia|estud|olh[ae] (o site|a p[áa]gina)|ver o que)\w*/i;
|
|
1549
|
+
const RE_CRIAR_DEPOIS = /\b(cri[ae]|faz|faça|mont[ae]|ger[ae]|escrev[ae]|produz|desenvolv)\w*/i;
|
|
1550
|
+
|
|
1551
|
+
/* A outra divisão que compensa: o pedido LONGO que emenda entregas diferentes
|
|
1552
|
+
("cria o site, depois põe login e publica"). Estreita de propósito — o
|
|
1553
|
+
planejador dividindo pedido de uma fase só era o "faz coisas nada a ver" —
|
|
1554
|
+
e o servidor ainda devolve passo único na dúvida. */
|
|
1555
|
+
const RE_ACAO = /\b(cri[ae]r?|fa[zç]a?|fazer|mont[ae]r?|ger[ae]r?|escrev[ae]r?|adicion[ae]r?|coloc[ae]r?|p[oõ]e|implement[ae]r?|public[ae]r?|sob[ea]|instal[ae]r?|configur[ae]r?|test[ae]r?|corrig[ei]r?|arrum[ae]r?|mud[ae]r?|integr[ae]r?|conect[ae]r?)\b/gi;
|
|
1556
|
+
function pedidoDeVariasPartes(pedido) {
|
|
1557
|
+
const t = String(pedido || '');
|
|
1558
|
+
if (t.length < 200) return false;
|
|
1559
|
+
const acoes = new Set((t.match(RE_ACAO) || []).map((x) => x.toLowerCase().slice(0, 4)));
|
|
1560
|
+
return acoes.size >= 3 && /\b(depois|em seguida|e tamb[ée]m|al[ée]m disso|por fim|e ent[ãa]o)\b|\n\s*(\d+[.)]|[-*•])\s/i.test(t);
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
/* "me manda o vídeo" resolvido na hora, sem gastar modelo.
|
|
1564
|
+
*
|
|
1565
|
+
* Antes isso abria a última criação do Studio no navegador com `#gravar`, e a
|
|
1566
|
+
* pessoa precisava aceitar uma permissão de tela para o navegador GRAVAR a
|
|
1567
|
+
* animação passando — era assim que o mp4 nascia.
|
|
1568
|
+
*
|
|
1569
|
+
* Isso acabou junto com o renderizador de navegador: o Remotion escreve o
|
|
1570
|
+
* arquivo direto, e todo render já deixa um .mp4 em `saida/`. Então "baixa o
|
|
1571
|
+
* vídeo" não é mais uma tarefa — é dizer onde ele está, que o CLI sabe sem
|
|
1572
|
+
* perguntar a modelo nenhum.
|
|
1573
|
+
*/
|
|
1574
|
+
const RE_BAIXAR = /\b(baixa\w*|exporta\w*|download|salva\w*|me manda|manda(r)? (o|a|esse|essa)|gera(r)? o arquivo|em mp4|pra mandar|arquivo do|onde (est[áa]|ficou))\b/i;
|
|
1575
|
+
const RE_PECA_STUDIO = /\b(v[ií]deo|mp4|apresenta[çc][ãa]o|slides?|reels?|anima[çc][ãa]o|filme)\b/i;
|
|
1576
|
+
|
|
1577
|
+
async function baixarCriacaoDireto(texto) {
|
|
1578
|
+
if (!(RE_BAIXAR.test(texto) && RE_PECA_STUDIO.test(texto))) return false;
|
|
1579
|
+
try {
|
|
1580
|
+
const { projeto } = require('../plugin/estudio');
|
|
1581
|
+
// O mais recente que já foi renderizado: quem diz "me manda o vídeo"
|
|
1582
|
+
// fala do último, e um projeto sem render não tem o que mandar.
|
|
1583
|
+
const comArquivo = projeto.listar({ limite: 30 })
|
|
1584
|
+
.find((p) => (p.renders || []).some((r) => fs.existsSync(r.arquivo)));
|
|
1585
|
+
if (!comArquivo) return false;
|
|
1586
|
+
const ultimo = [...comArquivo.renders].reverse().find((r) => fs.existsSync(r.arquivo));
|
|
1587
|
+
|
|
1588
|
+
await tools.execute('open_in_browser', { target: ultimo.arquivo },
|
|
1589
|
+
{ projectDir: state.workDir || os.homedir() });
|
|
1590
|
+
console.log(c.ok(` ⎿ abrindo "${comArquivo.titulo}"`));
|
|
1591
|
+
console.log(c.muted(' ') + c.white(ultimo.arquivo));
|
|
1592
|
+
console.log(c.dim(` ${(ultimo.bytes / 1048576).toFixed(1)} MB · o arquivo já estava pronto, é só copiar daí.`));
|
|
1593
|
+
return true;
|
|
1594
|
+
} catch {
|
|
1595
|
+
return false; // sem projeto renderizado: segue o caminho normal
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
/* Quantas vezes um passo que parou no meio é retomado sozinho. */
|
|
1600
|
+
const CONTINUACOES = 2;
|
|
1601
|
+
|
|
1602
|
+
/**
|
|
1603
|
+
* O pedido de retomada: o pedido original + o que já existe, para o agente
|
|
1604
|
+
* seguir em vez de recomeçar. A conversa do passo anterior não vai junto (é
|
|
1605
|
+
* ela que estourou) — vai o que aconteceu no disco, que é o que importa.
|
|
1606
|
+
*/
|
|
1607
|
+
function pedidoDeContinuacao(original, livro) {
|
|
1608
|
+
const linhas = [];
|
|
1609
|
+
if (livro.criados.length) linhas.push(`Arquivos criados: ${livro.criados.slice(0, 20).join(', ')}`);
|
|
1610
|
+
if (livro.alterados.length) linhas.push(`Arquivos alterados: ${livro.alterados.slice(0, 20).join(', ')}`);
|
|
1611
|
+
const cmds = livro.comandos.slice(-8).map((x) => `${x.comando} (${x.ok ? 'ok' : 'falhou'})`);
|
|
1612
|
+
if (cmds.length) linhas.push(`Comandos rodados: ${cmds.join('; ')}`);
|
|
1613
|
+
const falhas = livro.falhas.slice(-3).map((f) => `${f.acao}: ${f.motivo}`);
|
|
1614
|
+
if (falhas.length) linhas.push(`Falhas: ${falhas.join('; ')}`);
|
|
1615
|
+
return `CONTINUAÇÃO — a tarefa abaixo já foi começada e parou no meio. NÃO recomece do zero: `
|
|
1616
|
+
+ `leia o que já existe, veja o que falta, divida o que falta em passos pequenos (write_todos) e termine.\n\n`
|
|
1617
|
+
+ `O QUE JÁ FOI FEITO:\n${linhas.join('\n') || '(nada registrado)'}\n\nA TAREFA:\n${original}`;
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1620
|
+
async function dividirTarefa(pedido) {
|
|
1621
|
+
// O /plan já dividiu, e a pessoa aprovou: nada de chamar o servidor de novo.
|
|
1622
|
+
if (state.passosProntos) { const prontos = state.passosProntos; state.passosProntos = null; console.log(c.dim(` ⎿ ${prontos[0].titulo}`)); return prontos; }
|
|
1623
|
+
const inteiro = [{ titulo: 'tarefa', pedido }];
|
|
1624
|
+
if (!pedido || pedido.trim().length < 12) return inteiro;
|
|
1625
|
+
// Sem as duas fases no texto, nem chama o servidor: mais rápido, e sem
|
|
1626
|
+
// dar ao modelo a chance de dividir o que não devia.
|
|
1627
|
+
if (!(RE_DESCOBRIR.test(pedido) && RE_CRIAR_DEPOIS.test(pedido)) && !pedidoDeVariasPartes(pedido)) return inteiro;
|
|
1628
|
+
const sp = new Spinner('Primo Code pensando').start();
|
|
1629
|
+
try {
|
|
1630
|
+
const r = await api.requestPlano(state.config.server, {
|
|
1631
|
+
prompt: pedido, model: state.config.model, token: state.config.token,
|
|
1632
|
+
});
|
|
1633
|
+
sp.stop();
|
|
1634
|
+
const passos = (r && Array.isArray(r.passos) && r.passos.length) ? r.passos : inteiro;
|
|
1635
|
+
if (passos.length > 1) console.log(c.dim(` ⎿ ${passos[0].titulo}`));
|
|
1636
|
+
return passos;
|
|
1637
|
+
} catch {
|
|
1638
|
+
sp.stop(); // preparar o pedido é melhoria, não requisito
|
|
1639
|
+
return inteiro;
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
/**
|
|
1644
|
+
* Atualiza o resumo da conversa, se já compensar.
|
|
1645
|
+
*
|
|
1646
|
+
* Silencioso quando não há o que fazer: nas primeiras rodadas a conversa é
|
|
1647
|
+
* curta e o resumo não pagaria a chamada.
|
|
1648
|
+
*/
|
|
1649
|
+
/* `forcado` é o `/compact`: a pessoa mandou resumir, e mandar resumir tem de
|
|
1650
|
+
resumir. Sem isso o comando responderia "nada a fazer" justamente quando
|
|
1651
|
+
ela está vendo a IA se perder — e "não fiz nada" é a pior resposta possível
|
|
1652
|
+
para quem acabou de pedir socorro. */
|
|
1653
|
+
async function comprimirConversa(forcado = false, { silencioso = false } = {}) {
|
|
1654
|
+
if (!forcado && !memoria.precisaResumir(state.memoria, state.history)) return;
|
|
1655
|
+
// Em segundo plano não há spinner: ele disputaria a tela com o prompt.
|
|
1656
|
+
const sp = silencioso ? { stop() {} } : new Spinner('resumindo a conversa').start();
|
|
1657
|
+
try {
|
|
1658
|
+
const conversa = state.history;
|
|
1659
|
+
const dir = projectDir();
|
|
1660
|
+
/* A memória que o AGENTS.md desta pasta já tinha entra no resumo
|
|
1661
|
+
(uma vez por pasta): sem isto a primeira resposta de uma sessão nova
|
|
1662
|
+
reescreveria o AGENTS.md só com ela, e o "de onde parei" de ontem
|
|
1663
|
+
sumia. */
|
|
1664
|
+
if (!memoria.jaDobrou(state.memoria, dir) && !(state.memoria.semente && state.memoria.semente.pasta === dir)) {
|
|
1665
|
+
state.memoria = memoria.semear(state.memoria, dir, agentsMd.ler(dir));
|
|
1666
|
+
}
|
|
1667
|
+
// O mesmo `resumir` da compactação automática do agente (lib/session/compactacao.js): resumo + arquivos mexidos + to-dos.
|
|
1668
|
+
const nova = await memoria.atualizar(state.memoria, conversa, ({ resumo, mensagens }) =>
|
|
1669
|
+
require('../session/compactacao.js').resumirComFatos({ resumo, mensagens },
|
|
1670
|
+
(p) => api.requestResumo(state.config.server, { ...p, token: state.config.token }).then((r) => r.resumo)));
|
|
1671
|
+
// /clear ou /chats trocaram a conversa enquanto o resumo era feito:
|
|
1672
|
+
// o resumo é da conversa velha e não pode voltar por cima da nova.
|
|
1673
|
+
if (state.history !== conversa) { sp.stop(); return; }
|
|
1674
|
+
state.memoria = nova;
|
|
1675
|
+
sp.stop();
|
|
1676
|
+
gravarMemoriaDaPasta(dir);
|
|
1677
|
+
const e = memoria.economia(state.memoria, state.history);
|
|
1678
|
+
if (!silencioso && e.poupado > 0) console.log(c.dim(` ⎿ conversa resumida · ${e.cheio} → ${e.enxuto} tokens por pedido`));
|
|
1679
|
+
} catch {
|
|
1680
|
+
sp.stop(); // resumo é economia, não requisito: falhou, segue a vida
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1684
|
+
/* ── O RESUMO DE CADA RODADA ─────────────────────────────────────────────
|
|
1685
|
+
* "Gere um resumo a cada mensagem, pra na próxima ela ler só esse resumo."
|
|
1686
|
+
* O resumo começa assim que a resposta termina, atrás, sem segurar o prompt —
|
|
1687
|
+
* a pessoa lê a resposta enquanto ele é feito. O pedido seguinte espera por
|
|
1688
|
+
* ele (com teto: rede lenta não pode travar a conversa), e aí leva só o
|
|
1689
|
+
* resumo, não a conversa inteira. Ver lib/session/memoria-conversa.js. */
|
|
1690
|
+
function resumirDepois() {
|
|
1691
|
+
const anterior = state.resumindo || Promise.resolve();
|
|
1692
|
+
const atual = anterior.then(() => comprimirConversa(false, { silencioso: true })).catch(() => {});
|
|
1693
|
+
state.resumindo = atual;
|
|
1694
|
+
atual.then(() => { if (state.resumindo === atual) state.resumindo = null; });
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
/* ── O AGENTS.md DE CADA PASTA ───────────────────────────────────────────
|
|
1698
|
+
* "Eu preciso de um AGENTS.md com a memória da conversa em cada pasta."
|
|
1699
|
+
* O resumo da conversa vai para o AGENTS.md da pasta de trabalho (só o bloco
|
|
1700
|
+
* do PrimoCode; o resto do arquivo é da pessoa — lib/agents-md.js), e para a
|
|
1701
|
+
* pasta do projeto do Estúdio em que se mexeu, se houver. A raiz
|
|
1702
|
+
* ~/primocode fica de fora: é o corredor, não um projeto. */
|
|
1703
|
+
function gravarMemoriaDaPasta(dir = projectDir()) {
|
|
1704
|
+
const resumo = state.memoria && state.memoria.resumo;
|
|
1705
|
+
if (!resumo) return;
|
|
1706
|
+
try { agentsMd.gravar(dir, resumo, { raiz: cfg.ROOT_DIR }); } catch { /* memória é conveniência */ }
|
|
1707
|
+
if (state.estudioAtivo) {
|
|
1708
|
+
try {
|
|
1709
|
+
const p = require('../plugin/estudio/projeto.js').ler(state.estudioAtivo);
|
|
1710
|
+
if (p) agentsMd.gravar(p.pasta, resumo, { titulo: p.titulo });
|
|
1711
|
+
} catch { /* projeto sumiu */ }
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1715
|
+
async function esperarResumo(tetoMs = 6000) {
|
|
1716
|
+
if (!state.resumindo) return;
|
|
1717
|
+
await Promise.race([state.resumindo, new Promise((ok) => setTimeout(ok, tetoMs))]);
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
/* A linha que vai junto do resumo: em que projeto se está. É o que faz
|
|
1721
|
+
"continua o jogo" e "muda a cor" caírem no mesmo projeto em vez de inventar
|
|
1722
|
+
outro. */
|
|
1723
|
+
function mencoesDoPedido(userText) {
|
|
1724
|
+
const { arquivos, ignorados } = mencoesLib.mencoes(userText, projectDir());
|
|
1725
|
+
const lidos = [];
|
|
1726
|
+
for (const a of arquivos) {
|
|
1727
|
+
try {
|
|
1728
|
+
lidos.push({ path: a.rel, content: fs.readFileSync(a.abs, 'utf-8') });
|
|
1729
|
+
console.log(c.dim(` ⎿ anexado: ${a.rel} (${tools.fmtBytes(a.bytes)})`));
|
|
1730
|
+
} catch { console.log(c.dim(` ⎿ não consegui ler: ${a.rel}`)); }
|
|
1731
|
+
}
|
|
1732
|
+
for (const i of ignorados) console.log(c.dim(` ⎿ não anexei ${i.rel}: ${i.motivo}`));
|
|
1733
|
+
return lidos;
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1736
|
+
/* O pedido do /init. Passa pelo MESMO caminho de um pedido digitado
|
|
1737
|
+
(sendPrompt → runAct), então usa as ferramentas e o provedor de agora — um
|
|
1738
|
+
/init que falasse direto com o modelo não enxergaria os arquivos. */
|
|
1739
|
+
const PEDIDO_INIT = 'Estude este projeto (a pasta atual) e escreva um arquivo PRIMO.md na raiz dela. '
|
|
1740
|
+
+ 'Primeiro olhe de verdade: liste os arquivos, leia o README, o package.json (ou o equivalente) e os arquivos principais. '
|
|
1741
|
+
+ 'Depois escreva o PRIMO.md em português, curto (menos de 60 linhas), com estas seções: '
|
|
1742
|
+
+ 'o que é o projeto (2 ou 3 frases); como rodar (os comandos exatos que você viu, de instalar, rodar e testar); '
|
|
1743
|
+
+ 'a stack (linguagem, frameworks, banco); as convenções que o código segue (nomes, estilo, onde ficam os testes); '
|
|
1744
|
+
+ 'e onde está cada coisa (as pastas e arquivos que importam, uma linha cada). '
|
|
1745
|
+
+ 'Só escreva o que você conferiu nos arquivos — nada de inventar comando ou dependência. '
|
|
1746
|
+
+ 'Esse arquivo vai ser lido no começo de todo pedido neste projeto, então cada linha precisa valer o espaço.';
|
|
1747
|
+
|
|
1748
|
+
function contextoDoProjeto() {
|
|
1749
|
+
if (!state.currentProject) return '';
|
|
1750
|
+
return `Projeto atual: ${state.currentProject} (pasta ${shortPath(projectDir())}). `
|
|
1751
|
+
+ 'Pedidos como "continua", "edita", "muda", "melhora" ou "isso" são sobre ELE: '
|
|
1752
|
+
+ 'trabalhe nos arquivos que já existem lá, não crie outro projeto.';
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1755
|
+
/* O chat não passa pelo runAct, e é no runAct (buildMemoryContext) que as
|
|
1756
|
+
instruções do projeto entram. Sem isto o PRIMO.md valeria para o agente e
|
|
1757
|
+
seria ignorado quando o modo auto manda o pedido para a conversa. */
|
|
1758
|
+
function comInstrucoes(history) {
|
|
1759
|
+
const dir = state.currentProject || state.workDir ? projectDir() : null;
|
|
1760
|
+
let texto = mencoesLib.instrucoesDoProjeto(dir);
|
|
1761
|
+
// A memória do AGENTS.md também vale no chat, enquanto o resumo não a tem.
|
|
1762
|
+
const daPasta = dir && !memoria.jaDobrou(state.memoria, dir) ? agentsMd.ler(dir) : '';
|
|
1763
|
+
if (daPasta) texto = [texto, `[AGENTS.md — memória desta pasta: de onde a conversa parou]\n${daPasta}`].filter(Boolean).join('\n\n');
|
|
1764
|
+
return texto ? [{ role: 'system', content: texto }, ...history] : history;
|
|
1765
|
+
}
|
|
1766
|
+
|
|
1767
|
+
// O chat também precisa parar no Esc Esc. Sem isto o texto continuava saindo
|
|
1768
|
+
// na tela depois de o usuário ter mandado parar.
|
|
1769
|
+
let chatEmVoo = null;
|
|
1770
|
+
|
|
1771
|
+
/* O ouvinte de voz em segundo plano.
|
|
1772
|
+
Um por sessão: dois processos disputando o mesmo microfone dão um vazio
|
|
1773
|
+
intermitente que parece defeito de hardware e não é. */
|
|
1774
|
+
let vozPainel = null; // /voice painel: só o HUD
|
|
1775
|
+
let vozEmEspera = null; // a sessão do /voice: { processo, falar, calar }
|
|
1776
|
+
/* Por onde a fala entra no terminal. Nasce no main(), junto da fila — é lá
|
|
1777
|
+
que moram o `busy`, a fila e o `ask` pendente. */
|
|
1778
|
+
let entradaDeVoz = null;
|
|
1779
|
+
|
|
1780
|
+
async function runChat(promptForModel, userTextForMemory) {
|
|
1781
|
+
chatEmVoo = new AbortController();
|
|
1782
|
+
const sp = new Spinner(ui.PENSANDO).start();
|
|
1783
|
+
const saida = fala.fluxo();
|
|
1784
|
+
let text = '';
|
|
1785
|
+
// O chat não tinha a paciência do agente: o primeiro 429 ou teto do
|
|
1786
|
+
// minuto saía em vermelho na tela, na primeira recusa. Agora o que é
|
|
1787
|
+
// passageiro (minuto, 429, 5xx, rede) espera a janela e repete calado,
|
|
1788
|
+
// com o spinner de pensar girando — até seis vezes. O que NÃO é
|
|
1789
|
+
// passageiro (crédito, chave, cota do dia) continua saindo, como aviso.
|
|
1790
|
+
// Texto já na tela não se repete: se o erro veio no meio da resposta, ela
|
|
1791
|
+
// fica como está e o aviso vem embaixo.
|
|
1792
|
+
for (let tentativa = 0; ; tentativa++) {
|
|
1793
|
+
let erro = null;
|
|
1794
|
+
try {
|
|
1795
|
+
await api.requestChat(state.config.server, {
|
|
1796
|
+
prompt: promptForModel,
|
|
1797
|
+
history: comInstrucoes(memoria.paraEnviar(state.memoria, state.history, contextoDoProjeto())),
|
|
1798
|
+
model: state.config.model,
|
|
1799
|
+
token: state.config.token,
|
|
1800
|
+
sinal: chatEmVoo.signal,
|
|
1801
|
+
}, (evt) => {
|
|
1802
|
+
if (evt.erro) { erro = evt.erro; return; }
|
|
1803
|
+
if (evt.delta) {
|
|
1804
|
+
if (!saida.escreveu()) sp.stop();
|
|
1805
|
+
text += evt.delta;
|
|
1806
|
+
saida.escrever(evt.delta);
|
|
1807
|
+
}
|
|
1808
|
+
});
|
|
1809
|
+
} catch (e) { erro = e; }
|
|
1810
|
+
if (!erro) break;
|
|
1811
|
+
const passageiro = ehTetoDeToken(erro) || ehTransitorio(erro);
|
|
1812
|
+
if (passageiro && tentativa < 6 && !text && !chatEmVoo.signal.aborted) {
|
|
1813
|
+
await new Promise((r) => setTimeout(r, esperaDoErro(erro, tentativa + 1)));
|
|
1814
|
+
continue;
|
|
1815
|
+
}
|
|
1816
|
+
sp.stop();
|
|
1817
|
+
saida.fechar();
|
|
1818
|
+
if (!chatEmVoo.signal.aborted) fala.problema(erro);
|
|
1819
|
+
if (!text) return;
|
|
1820
|
+
break;
|
|
1821
|
+
}
|
|
1822
|
+
sp.stop();
|
|
1823
|
+
saida.fechar();
|
|
1824
|
+
if (text) {
|
|
1825
|
+
state.history.push({ role: 'user', content: userTextForMemory });
|
|
1826
|
+
state.history.push({ role: 'assistant', content: text });
|
|
1827
|
+
resumirDepois();
|
|
1828
|
+
state.lastResponse = text;
|
|
1829
|
+
cfg.appendHistory({ mode: 'chat', prompt: userTextForMemory });
|
|
1830
|
+
state.gravador.turno(userTextForMemory, text, { modo: 'chat' });
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1834
|
+
// ── Slash commands ─────────────────────────────────────────────────────
|
|
1835
|
+
|
|
1836
|
+
function isSlash(text) { return text.trim().startsWith('/'); }
|
|
1837
|
+
|
|
1838
|
+
/* ── "!comando" RODA NO SHELL ────────────────────────────────────────────
|
|
1839
|
+
*
|
|
1840
|
+
* "quando eu mande uma mensagem que comece com ! ele rode em bash"
|
|
1841
|
+
*
|
|
1842
|
+
* Por que não mandar ao agente e deixar ele chamar run_shell: porque são
|
|
1843
|
+
* coisas diferentes. Pedir ao agente é dizer o QUE se quer e deixá-lo
|
|
1844
|
+
* decidir; o "!" é dizer o COMANDO. Quem digita `!git status` não quer que
|
|
1845
|
+
* alguém interprete a intenção — quer a saída do git status, agora, sem
|
|
1846
|
+
* volta ao modelo, sem gastar cota e sem o risco de o agente achar que
|
|
1847
|
+
* entendeu melhor.
|
|
1848
|
+
*
|
|
1849
|
+
* A saída sai CRUA, como no terminal: ela não passa pelo desenhador de
|
|
1850
|
+
* Markdown. Saída de comando tem alinhamento próprio (colunas do `ls`,
|
|
1851
|
+
* tabela do `docker ps`), e reformatá-la seria estragá-la.
|
|
1852
|
+
*/
|
|
1853
|
+
function ehBash(text) { return /^\s*!/.test(String(text || '')); }
|
|
1854
|
+
|
|
1855
|
+
async function rodarBash(text) {
|
|
1856
|
+
const comando = String(text).replace(/^\s*!/, '').trim();
|
|
1857
|
+
if (!comando) return;
|
|
1858
|
+
|
|
1859
|
+
const pasta = state.workDir || process.cwd();
|
|
1860
|
+
console.log('');
|
|
1861
|
+
console.log(' ' + c.warn('$ ') + c.white(comando));
|
|
1862
|
+
|
|
1863
|
+
const inicio = Date.now();
|
|
1864
|
+
const r = await tools.execute('run_shell', { command: comando, timeout: 600000 },
|
|
1865
|
+
{ projectDir: pasta });
|
|
1866
|
+
const segundos = ((Date.now() - inicio) / 1000).toFixed(1);
|
|
1867
|
+
|
|
1868
|
+
/* Crua, e inteira. `run_shell` corta em 10 MB, que é o teto do buffer;
|
|
1869
|
+
cortar mais aqui esconderia justamente a linha do erro, que costuma
|
|
1870
|
+
estar no fim. */
|
|
1871
|
+
const saida = [r.stdout, r.stderr].filter((x) => String(x || '').trim()).join('\n');
|
|
1872
|
+
if (saida) console.log(saida.replace(/\n$/, ''));
|
|
1873
|
+
|
|
1874
|
+
if (r.ok) {
|
|
1875
|
+
console.log(' ' + c.dim(`ok · ${segundos}s`));
|
|
1876
|
+
} else if (r.killed) {
|
|
1877
|
+
console.log(' ' + c.warn(`interrompido depois de ${segundos}s`));
|
|
1878
|
+
} else {
|
|
1879
|
+
console.log(' ' + c.warn(`saiu com ${r.code} · ${segundos}s`));
|
|
1880
|
+
}
|
|
1881
|
+
console.log('');
|
|
1882
|
+
|
|
1883
|
+
/* O agente FICA SABENDO, e isto é o que torna o "!" útil dentro de uma
|
|
1884
|
+
conversa: rodar o teste e depois perguntar "por que falhou?" só
|
|
1885
|
+
funciona se ele tiver visto a saída. Sem isto seriam dois mundos
|
|
1886
|
+
separados na mesma tela. */
|
|
1887
|
+
state.history.push({ role: 'user', content: `Rodei no shell: ${comando}` });
|
|
1888
|
+
state.history.push({
|
|
1889
|
+
role: 'assistant',
|
|
1890
|
+
content: `Saída (código ${r.code ?? 0}):\n${saida.slice(0, 4000) || '(vazia)'}`,
|
|
1891
|
+
});
|
|
1892
|
+
resumirDepois();
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
/* ── OS NOMES ANTIGOS ────────────────────────────────────────────────────
|
|
1896
|
+
* Os comandos são todos em inglês curto e o nome antigo NÃO some: ele responde
|
|
1897
|
+
* e ensina o novo. Sumir de vez faz quem tem o dedo viciado achar que a
|
|
1898
|
+
* atualização quebrou — e essa pessoa não procura no /help, desinstala.
|
|
1899
|
+
* A tabela (apelido → nome novo, e os 9 grupos) mora em lib/nomes.js. */
|
|
1900
|
+
|
|
1901
|
+
/* Abrir uma conversa salva e seguir dela. Uma função só, para o /chats n e o
|
|
1902
|
+
`primo -c` carregarem a conversa do MESMO jeito: dois caminhos divergiriam
|
|
1903
|
+
no primeiro detalhe (a memória, o gravador) e um deles gravaria errado. */
|
|
1904
|
+
async function abrirConversa(alvo) {
|
|
1905
|
+
const sp = new Spinner('abrindo').start();
|
|
1906
|
+
const conv = await nuvem.lerConversa(alvo.id);
|
|
1907
|
+
sp.stop();
|
|
1908
|
+
if (!conv.ok) return conv;
|
|
1909
|
+
// A memória entra ZERADA: o resumo antigo não veio junto, e um
|
|
1910
|
+
// resumo de outra conversa colado aqui faria o modelo responder
|
|
1911
|
+
// sobre coisa que não foi dita nesta.
|
|
1912
|
+
state.history = conv.mensagens.map((m) => ({
|
|
1913
|
+
role: m.papel, content: m.texto,
|
|
1914
|
+
}));
|
|
1915
|
+
state.memoria = memoria.nova();
|
|
1916
|
+
state.gravador.retomar(alvo.id, alvo.titulo, conv.mensagens.length);
|
|
1917
|
+
return conv;
|
|
1918
|
+
}
|
|
1919
|
+
|
|
1920
|
+
/* `primo --continue` / `primo -c`: volta na última conversa, sem passar pelo
|
|
1921
|
+
/chats. A lista do servidor já vem da mais recente para a mais antiga, então
|
|
1922
|
+
a última é a primeira. Sem conta ou sem conversa, começa do zero e diz. */
|
|
1923
|
+
async function continuarUltima() {
|
|
1924
|
+
if (!conta.atual()) {
|
|
1925
|
+
console.log(c.dim(' ⎿ sem conta conectada, não há conversa para continuar — começando do zero'));
|
|
1926
|
+
return false;
|
|
1927
|
+
}
|
|
1928
|
+
const l = await nuvem.listarConversas({ limite: 1 });
|
|
1929
|
+
const alvo = l.ok && l.conversas[0];
|
|
1930
|
+
if (!alvo) {
|
|
1931
|
+
console.log(c.dim(' ⎿ nenhuma conversa salva ainda — começando do zero'));
|
|
1932
|
+
return false;
|
|
1933
|
+
}
|
|
1934
|
+
const conv = await abrirConversa(alvo);
|
|
1935
|
+
if (!conv.ok) {
|
|
1936
|
+
console.log(c.dim(` ⎿ não consegui abrir a última conversa (${conv.error}) — começando do zero`));
|
|
1937
|
+
return false;
|
|
1938
|
+
}
|
|
1939
|
+
const quando = alvo.atualizada ? new Date(alvo.atualizada).toLocaleString('pt-BR') : 'data desconhecida';
|
|
1940
|
+
console.log(c.dim(` ⎿ continuando: ${alvo.titulo.slice(0, 60)} (${quando})`));
|
|
1941
|
+
return true;
|
|
1942
|
+
}
|
|
1943
|
+
|
|
1944
|
+
/* /resume e --resume: sem referência lista as conversas; com número ou id, retoma. */
|
|
1945
|
+
async function retomarConversa(ref, { listar = true } = {}) {
|
|
1946
|
+
if (!conta.atual()) { console.log(c.muted(' Não conectado. ') + c.brand('/login') + c.muted(' para retomar conversas.')); return false; }
|
|
1947
|
+
const l = await nuvem.listarConversas({ limite: 20 });
|
|
1948
|
+
if (!l.ok) { console.log(c.err(` ${l.error}`)); return false; }
|
|
1949
|
+
if (!l.conversas.length) { console.log(c.muted(' Nenhuma conversa salva ainda.')); return false; }
|
|
1950
|
+
if (!ref) {
|
|
1951
|
+
if (!listar) return false;
|
|
1952
|
+
console.log(c.white('\n Conversas recentes'));
|
|
1953
|
+
l.conversas.forEach((x, i) => console.log(' ' + c.dim(String(i + 1).padStart(2)) + ' ' + c.white(x.titulo.slice(0, 52).padEnd(52))
|
|
1954
|
+
+ c.dim(`${String(x.mensagens).padStart(3)} msg ${x.atualizada ? new Date(x.atualizada).toLocaleDateString('pt-BR') : '—'}`)));
|
|
1955
|
+
console.log(c.dim('\n /resume <número ou id> retoma.'));
|
|
1956
|
+
return false;
|
|
1957
|
+
}
|
|
1958
|
+
const alvo = retomar.escolher(l.conversas, ref);
|
|
1959
|
+
if (!alvo) { console.log(c.err(` Não achei a conversa ${ref}.`)); return false; }
|
|
1960
|
+
const conv = await abrirConversa(alvo);
|
|
1961
|
+
if (!conv.ok) { console.log(c.err(` ${conv.error}`)); return false; }
|
|
1962
|
+
console.log(c.ok(` ${alvo.titulo}`) + c.muted(` · ${conv.mensagens.length} mensagens carregadas`));
|
|
1963
|
+
return true;
|
|
1964
|
+
}
|
|
1965
|
+
|
|
1966
|
+
/* `--resume` sem id: mostra a lista e pergunta o número (só em terminal). */
|
|
1967
|
+
async function escolherNaAbertura() {
|
|
1968
|
+
await retomarConversa(null);
|
|
1969
|
+
if (!process.stdin.isTTY) return false;
|
|
1970
|
+
const rl = require('readline').createInterface({ input: process.stdin, output: process.stdout });
|
|
1971
|
+
const resp = await new Promise((res) => rl.question(' Qual? (número, Enter cancela) ', res));
|
|
1972
|
+
rl.close();
|
|
1973
|
+
return resp.trim() ? retomarConversa(resp.trim()) : false;
|
|
1974
|
+
}
|
|
1975
|
+
|
|
1976
|
+
/* /worktree <nome>: cria e entra. */
|
|
1977
|
+
function entrarNoWorktree(nome) {
|
|
1978
|
+
const w = retomar.criarWorktree(nome, projectDir());
|
|
1979
|
+
if (!w.ok) { console.log(c.err(` ${w.error}`)); return false; }
|
|
1980
|
+
entrarNoProjeto(w.path, '/dir');
|
|
1981
|
+
console.log(c.ok(` worktree ${shortPath(w.path)}`) + c.muted(` · branch ${w.branch}`));
|
|
1982
|
+
return true;
|
|
1983
|
+
}
|
|
1984
|
+
|
|
1985
|
+
/* /new sem nada: as 3 perguntas (era o /new). */
|
|
1986
|
+
async function comecarPerguntas() {
|
|
1987
|
+
const comecar = require('./comecar');
|
|
1988
|
+
let oque = (await ask(' O que você quer criar? Conte do seu jeito. (Enter: ver ideias)\n > ')).trim();
|
|
1989
|
+
if (!oque) {
|
|
1990
|
+
// Sem ideia não é motivo pra desistir: mostra por onde começar.
|
|
1991
|
+
console.log(c.muted('\n Algumas ideias pra começar:'));
|
|
1992
|
+
comecar.IDEIAS.forEach((ideia, i) => console.log(` ${c.brand(String(i + 1))} ${ideia}`));
|
|
1993
|
+
oque = comecar.escolherIdeia(await ask('\n Escolha um número, ou escreva a sua ideia (Enter cancela)\n > ')) || '';
|
|
1994
|
+
}
|
|
1995
|
+
if (!oque) { console.log(c.muted(' Tudo bem, sem pressa. Quando quiser, é só digitar /new de novo.')); return; }
|
|
1996
|
+
console.log(c.muted(` → ${oque}`));
|
|
1997
|
+
const praQuem = (await ask(' Pra quem é? (Enter pula)\n > ')).trim();
|
|
1998
|
+
const onde = (await ask(' Abre onde: no navegador, no celular, ou tanto faz? (Enter pula)\n > ')).trim();
|
|
1999
|
+
await criarProjetoNovo(comecar.montarPedidoComecar({ oque, praQuem, onde }));
|
|
2000
|
+
// quem acabou de fazer o primeiro app não sabe que pode conferir nem voltar: é a hora de contar
|
|
2001
|
+
console.log(c.muted(`\n ${comecar.DEPOIS_DO_PRIMEIRO_APP}`));
|
|
2002
|
+
return;
|
|
2003
|
+
}
|
|
2004
|
+
|
|
2005
|
+
/* /attach <url>: a página vira texto e vai junto do próximo pedido (lib/web-pagina.js). */
|
|
2006
|
+
async function anexarPagina(rest) {
|
|
2007
|
+
const sp = new Spinner('lendo a página').start();
|
|
2008
|
+
const r = await require('../web-pagina.js').baixar(rest.trim());
|
|
2009
|
+
sp.stop();
|
|
2010
|
+
if (!r.ok) { console.log(c.err(` Não anexei: ${r.error}.`)); return; }
|
|
2011
|
+
state.attachedFiles.push({ path: r.url, content: (r.titulo ? `# ${r.titulo}\n\n` : '') + r.texto });
|
|
2012
|
+
console.log(c.ok(` Anexei: ${r.titulo || r.url}`) + c.muted(` · ${r.palavras} palavras${r.cortado ? ' (o começo da página)' : ''}`));
|
|
2013
|
+
console.log(c.muted(' Vai junto do próximo pedido. /attach mostra, /detach tira.'));
|
|
2014
|
+
refreshPrompt();
|
|
2015
|
+
return;
|
|
2016
|
+
}
|
|
2017
|
+
|
|
2018
|
+
/* /attach sem nada: o que está anexado. */
|
|
2019
|
+
function listarAnexos() {
|
|
2020
|
+
if (!state.attachedFiles.length) console.log(c.muted('Nenhum arquivo anexado.'));
|
|
2021
|
+
else state.attachedFiles.forEach((f) => console.log(` ${c.brand(f.path)} ${c.muted(tools.fmtBytes(f.content.length))}`));
|
|
2022
|
+
}
|
|
2023
|
+
|
|
2024
|
+
/* /help all: tudo que ele sabe fazer (lib/skill/catalogo.js). */
|
|
2025
|
+
function mostrarTudo() {
|
|
2026
|
+
const cols = Math.max(40, Math.min(process.stdout.columns || 90, 110));
|
|
2027
|
+
console.log('');
|
|
2028
|
+
for (const g of catalogo.GRUPOS) {
|
|
2029
|
+
console.log(' ' + c.bold(c.white(g.nome)) + ' ' + ui.truncate(c.dim('— ' + g.resumo), cols - 4 - ui.visibleWidth(g.nome)));
|
|
2030
|
+
for (const i of g.itens) {
|
|
2031
|
+
console.log(' ' + c.brand(ui.padRight(i.tool, 23)) + ui.truncate(c.muted(i.faz), cols - 28));
|
|
2032
|
+
}
|
|
2033
|
+
console.log('');
|
|
2034
|
+
}
|
|
2035
|
+
console.log(c.dim(` ${catalogo.TODAS.length} ferramentas. Você não precisa saber nenhum desses nomes — peça em português.`));
|
|
2036
|
+
return;
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
/* /taste referencias: a tela pra soltar os motions que você curtiu. */
|
|
2040
|
+
async function abrirReferencias() {
|
|
2041
|
+
const G = require('../plugin/estudio/gosto.js');
|
|
2042
|
+
console.log(c.muted(process.env.PRIMOCODE_APP === '1' ? ' Abri a tela do gosto (até 10 min): solte os vídeos que você curtiu e salve.' : ' Abri uma tela no navegador (até 10 min): solte os vídeos que você curtiu e salve.'));
|
|
2043
|
+
const r = await G.abrirOndeDer({ inicio: 'referencias' });
|
|
2044
|
+
if (!r.ok) console.log(c.warn(r.motivo === 'pulou' ? ' Você pulou: nada foi salvo.' : r.motivo === 'tempo' ? ' Acabou o tempo: nada foi salvo.' : r.motivo === 'fechou' ? ' Você fechou a tela: nada foi salvo.' : ' Não consegui abrir a tela.'));
|
|
2045
|
+
const rs = G.resumo(G.ler());
|
|
2046
|
+
console.log(rs ? c.muted(' ') + rs : c.muted(' Ainda não tem gosto salvo. /taste referencias abre a tela.'));
|
|
2047
|
+
return;
|
|
2048
|
+
}
|
|
2049
|
+
|
|
2050
|
+
/* /doctor status: só o servidor, a versão e a conversa. */
|
|
2051
|
+
async function mostrarStatus() {
|
|
2052
|
+
const sp = new Spinner('verificando').start();
|
|
2053
|
+
try {
|
|
2054
|
+
const h = await api.getHealth(state.config.server, state.config.token);
|
|
2055
|
+
sp.stop();
|
|
2056
|
+
console.log(c.ok(`Servidor: ${h.status || 'ok'}`));
|
|
2057
|
+
if (h.version) console.log(c.muted(` Versão: ${h.version}`));
|
|
2058
|
+
if (h.model) console.log(c.muted(` Modelo: ${h.model}`) + (h.gratis ? c.dim(' · grátis') : ''));
|
|
2059
|
+
// A corrente inteira: é o que garante que um modelo no limite não
|
|
2060
|
+
// vira erro na sua tela.
|
|
2061
|
+
if (h.correntes && h.correntes[state.config.model || 'main']) {
|
|
2062
|
+
const fila = h.correntes[state.config.model] || h.correntes.main;
|
|
2063
|
+
console.log(c.dim(` Reservas: ${fila.length - 1}`));
|
|
2064
|
+
}
|
|
2065
|
+
} catch (e) { sp.stop(); console.log(c.err(`Indisponível: ${e.message}`)); }
|
|
2066
|
+
// A memória da conversa: quanto ela está poupando por pedido.
|
|
2067
|
+
if (state.history.length) {
|
|
2068
|
+
const e = memoria.economia(state.memoria, state.history);
|
|
2069
|
+
console.log(c.muted(` Conversa: ${state.history.length} mensagens`)
|
|
2070
|
+
+ (state.memoria.resumo
|
|
2071
|
+
? c.dim(` · resumida, ${e.enxuto} tokens por pedido em vez de ${e.cheio}`)
|
|
2072
|
+
: c.dim(` · ${e.enxuto} tokens por pedido`)));
|
|
2073
|
+
}
|
|
2074
|
+
return;
|
|
2075
|
+
}
|
|
2076
|
+
|
|
2077
|
+
/* /account plans: os planos e o link pra assinar. */
|
|
2078
|
+
async function mostrarPlanos() {
|
|
2079
|
+
const sp = new Spinner('buscando os planos').start();
|
|
2080
|
+
const r = await planosTela.buscarPlanos(state.config.server);
|
|
2081
|
+
sp.stop();
|
|
2082
|
+
const eu = conta.atual();
|
|
2083
|
+
for (const l of planosTela.desenhar(r, { cores: c, atual: eu && eu.pro ? eu.plano : null, site: conta.SITE })) console.log(l);
|
|
2084
|
+
return;
|
|
2085
|
+
}
|
|
2086
|
+
|
|
2087
|
+
async function handleSlash(text) {
|
|
2088
|
+
const [cmd] = text.trim().slice(1).split(/\s+/);
|
|
2089
|
+
const restoDigitado = text.trim().slice(1 + cmd.length).trim();
|
|
2090
|
+
|
|
2091
|
+
let nome = cmd.toLowerCase();
|
|
2092
|
+
const apelido = nomes.ehApelido(nome);
|
|
2093
|
+
// O comando da própria pessoa com o nome antigo (um ~/.primocode/comandos/revisar.md) ganha do apelido.
|
|
2094
|
+
const dela = apelido && comandosDaPessoa().find((x) => x.nome === nome && x.origem !== 'primocode');
|
|
2095
|
+
let rest = restoDigitado;
|
|
2096
|
+
if (apelido && !dela) {
|
|
2097
|
+
const junto = nomes.PREFIXO[nome];
|
|
2098
|
+
console.log(c.muted(' Agora é ') + c.brand('/' + apelido + (junto ? ' ' + junto : '')) + c.muted('.'));
|
|
2099
|
+
nome = apelido;
|
|
2100
|
+
if (junto) rest = `${junto} ${restoDigitado}`.trim(); // /account plans vira /account plans
|
|
2101
|
+
}
|
|
2102
|
+
|
|
2103
|
+
switch (nome) {
|
|
2104
|
+
case 'help': if (/^(all|tudo)$/i.test(rest)) mostrarTudo(); else console.log(montarHelp()); break;
|
|
2105
|
+
|
|
2106
|
+
case 'resume': await retomarConversa(rest); break;
|
|
2107
|
+
case 'worktree':
|
|
2108
|
+
if (!rest) console.log(c.muted(' Uso: /worktree <nome> (cria ../<repo>-<nome> numa branch nova e entra)'));
|
|
2109
|
+
else entrarNoWorktree(rest.split(/\s+/)[0]);
|
|
2110
|
+
break;
|
|
2111
|
+
|
|
2112
|
+
/* /projetos e /project sem nome são a MESMA lista: antes o /project só
|
|
2113
|
+
listava os nomes, em ordem alfabética, e quem procurava "o de ontem"
|
|
2114
|
+
tinha de abrir pasta por pasta. Agora vem do mais recente, com
|
|
2115
|
+
quando mexeu e o tamanho, e um número para entrar. */
|
|
2116
|
+
case 'projects': {
|
|
2117
|
+
const lista = extra.listarProjetos(cfg.ROOT_DIR);
|
|
2118
|
+
const numero = /^\d+$/.test(rest) ? Number(rest) : 0;
|
|
2119
|
+
if (!rest || (numero && cmd.toLowerCase() === 'projetos') || (numero && numero <= lista.length)) {
|
|
2120
|
+
if (!lista.length) { console.log(c.muted(' Nenhum projeto ainda. Peça algo e eu crio o primeiro.')); break; }
|
|
2121
|
+
if (numero) {
|
|
2122
|
+
const alvo = lista[numero - 1];
|
|
2123
|
+
if (!alvo) { console.log(c.err(` Não há projeto ${numero}. São ${lista.length}.`)); break; }
|
|
2124
|
+
entrarNoProjeto(alvo.dir, 'projeto');
|
|
2125
|
+
console.log(c.ok(` Trabalhando em ${alvo.nome}`) + c.muted(` (${shortPath(alvo.dir)})`));
|
|
2126
|
+
refreshPrompt();
|
|
2127
|
+
break;
|
|
2128
|
+
}
|
|
2129
|
+
console.log('');
|
|
2130
|
+
const largura = Math.min(34, Math.max(...lista.map((x) => x.nome.length)));
|
|
2131
|
+
lista.forEach((x, i) => {
|
|
2132
|
+
const aqui = x.nome === state.currentProject;
|
|
2133
|
+
const nomeCol = ui.padRight(ui.truncate(aqui ? c.brand(x.nome) : c.white(x.nome), largura), largura);
|
|
2134
|
+
console.log(` ${aqui ? c.brand('●') : ' '} ${c.dim(String(i + 1).padStart(2))} ${nomeCol} `
|
|
2135
|
+
+ c.muted(ui.padRight(extra.quandoFoi(x.modificado), 11))
|
|
2136
|
+
+ c.dim(`${extra.fmtTamanho(x.bytes)}${x.cortado ? '+' : ''} · ${x.arquivos} arq.`));
|
|
2137
|
+
});
|
|
2138
|
+
console.log(c.dim(`\n ${shortPath(cfg.ROOT_DIR)} · /projects 1 entra no primeiro · /new <descrição> começa outro`));
|
|
2139
|
+
break;
|
|
2140
|
+
}
|
|
2141
|
+
const dir = cfg.createProjectDir(rest);
|
|
2142
|
+
entrarNoProjeto(dir, 'projeto');
|
|
2143
|
+
console.log(c.ok(`Projeto: ${state.currentProject}`) + c.muted(` (${dir})`));
|
|
2144
|
+
refreshPrompt();
|
|
2145
|
+
break;
|
|
2146
|
+
}
|
|
2147
|
+
|
|
2148
|
+
// Antes só existia /project, que SEMPRE cria em ~/primocode/<nome>. Se a
|
|
2149
|
+
// sua pasta já existe em outro lugar, não havia como apontar para ela.
|
|
2150
|
+
case 'dir': {
|
|
2151
|
+
if (!rest) {
|
|
2152
|
+
const de = {
|
|
2153
|
+
padrao: 'a pasta padrão do PrimoCode',
|
|
2154
|
+
'/dir': 'você escolheu com /dir',
|
|
2155
|
+
detectada: 'você falou dela no pedido',
|
|
2156
|
+
projeto: 'projeto do PrimoCode',
|
|
2157
|
+
};
|
|
2158
|
+
console.log(` ${c.white(shortPath(projectDir()))}`);
|
|
2159
|
+
console.log(c.muted(` ${de[state.workDirOrigem] || 'pasta atual do terminal'}`));
|
|
2160
|
+
console.log(c.dim(' /dir <caminho> muda · /project <nome> cria uma nova em ~/primocode'));
|
|
2161
|
+
break;
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2164
|
+
// ~ e caminho relativo resolvem contra a pasta ativa, não contra o
|
|
2165
|
+
// cwd do processo: depois de um /dir, "src" é dentro dela.
|
|
2166
|
+
const bruto = rest.replace(/^~(?=$|[/\\])/, os.homedir());
|
|
2167
|
+
const alvo = path.resolve(projectDir(), bruto);
|
|
2168
|
+
|
|
2169
|
+
if (!fs.existsSync(alvo)) {
|
|
2170
|
+
if (!(await confirm(`A pasta ${shortPath(alvo)} não existe. Criar?`))) {
|
|
2171
|
+
console.log(c.muted(' Nada mudou.'));
|
|
2172
|
+
break;
|
|
2173
|
+
}
|
|
2174
|
+
try { fs.mkdirSync(alvo, { recursive: true }); }
|
|
2175
|
+
catch (e) { console.log(c.err(` Não consegui criar: ${e.message}`)); break; }
|
|
2176
|
+
} else if (!fs.statSync(alvo).isDirectory()) {
|
|
2177
|
+
console.log(c.err(` ${shortPath(alvo)} é um arquivo, não uma pasta.`));
|
|
2178
|
+
break;
|
|
2179
|
+
}
|
|
2180
|
+
|
|
2181
|
+
// A home e a raiz do disco são recusadas por padrão em qualquer
|
|
2182
|
+
// lugar do código — aqui o pedido é explícito, então pergunta em vez
|
|
2183
|
+
// de recusar, mas pergunta mesmo: é onde um write_file erra feio.
|
|
2184
|
+
if (!pastaSegura(alvo)) {
|
|
2185
|
+
console.log(c.warn(` ${shortPath(alvo)} é a sua home ou a raiz do disco.`));
|
|
2186
|
+
if (!(await confirm('O agente pode criar e editar arquivos aí. Confirma?'))) {
|
|
2187
|
+
console.log(c.muted(' Nada mudou.'));
|
|
2188
|
+
break;
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
|
|
2192
|
+
entrarNoProjeto(alvo, '/dir');
|
|
2193
|
+
const quantos = (() => { try { return fs.readdirSync(alvo).length; } catch { return 0; } })();
|
|
2194
|
+
console.log(c.ok(` Trabalhando em ${shortPath(alvo)}`) + c.muted(` (${quantos} ${quantos === 1 ? 'item' : 'itens'})`));
|
|
2195
|
+
refreshPrompt();
|
|
2196
|
+
break;
|
|
2197
|
+
}
|
|
2198
|
+
|
|
2199
|
+
/* Quando ele pergunta antes de agir. Os três modos e o porquê de cada
|
|
2200
|
+
um estão em lib/permission/perigo.js. */
|
|
2201
|
+
/* Os motions que a pessoa curtiu: ela solta os vídeos na tela e o PrimoCode mede e soma no gosto (gosto-medir.js). */
|
|
2202
|
+
|
|
2203
|
+
/* O gosto de motion: a tela abre sozinha no primeiro estudio_motion; aqui dá pra ver, refazer ou apagar. */
|
|
2204
|
+
case 'taste': {
|
|
2205
|
+
const G = require('../plugin/estudio/gosto.js');
|
|
2206
|
+
const a = String(rest || '').trim().toLowerCase();
|
|
2207
|
+
if (/^(referencias|ref|refs)$/.test(a)) { await abrirReferencias(); break; }
|
|
2208
|
+
if (a === 'apagar') {
|
|
2209
|
+
try { fs.unlinkSync(G.arquivo()); console.log(c.ok(' Gosto de motion apagado. O próximo motion pergunta de novo.')); }
|
|
2210
|
+
catch { console.log(c.muted(' Não havia gosto salvo.')); }
|
|
2211
|
+
break;
|
|
2212
|
+
}
|
|
2213
|
+
if (a === 'refazer') {
|
|
2214
|
+
console.log(c.muted(' Abri uma tela no navegador (até 10 min). Feche ou pule pra voltar.'));
|
|
2215
|
+
const r = await G.abrirOndeDer();
|
|
2216
|
+
if (!r.ok) console.log(c.warn(r.motivo === 'pulou' ? ' Você pulou: sem gosto salvo.' : r.motivo === 'tempo' ? ' Acabou o tempo: nada foi salvo.' : ' Não consegui abrir a tela.'));
|
|
2217
|
+
} else if (/^provar\b/.test(a)) {
|
|
2218
|
+
const assunto = String(rest).trim().replace(/^provar\s*/i, '') || 'um vídeo de apresentação';
|
|
2219
|
+
const P = require('../plugin/estudio/gosto-prova.js');
|
|
2220
|
+
for (const l of P.texto(P.provar(G.pesos(G.ler()), { assunto }), assunto)) console.log(' ' + l);
|
|
2221
|
+
break;
|
|
2222
|
+
} else if (/^for[cç]a\s+\S/.test(a)) {
|
|
2223
|
+
const r = G.definirForca(a.replace(/^for[cç]a\s+/, ''));
|
|
2224
|
+
if (!r.ok) { console.log(c.err(` ${r.error}`)); break; }
|
|
2225
|
+
console.log(c.ok(` Força das referências: ${{ pouco: 'pouco (só sugerem)', medio: 'médio', muito: 'muito (puxam forte)' }[r.forca]}.`));
|
|
2226
|
+
} else if (/^salvar\s+\S/.test(a)) {
|
|
2227
|
+
const r = G.salvarEstilo(String(rest).trim().replace(/^salvar\s+/i, ''));
|
|
2228
|
+
console.log(r.ok ? c.ok(` Estilo "${r.nome}" salvo. /taste usar ${r.nome} volta pra ele quando quiser.`) : c.err(` ${r.error}`));
|
|
2229
|
+
break;
|
|
2230
|
+
} else if (/^usar\s+\S/.test(a)) {
|
|
2231
|
+
const r = G.usarEstilo(String(rest).trim().replace(/^usar\s+/i, ''));
|
|
2232
|
+
if (!r.ok) { console.log(c.err(` ${r.error}`)); break; }
|
|
2233
|
+
console.log(c.ok(` Agora o gosto em uso é o "${r.nome}".`));
|
|
2234
|
+
} else if (a === 'estilos') {
|
|
2235
|
+
const lista = G.estilos();
|
|
2236
|
+
console.log(lista.length ? ' Estilos salvos: ' + lista.join(', ') + c.muted(' · /taste usar <nome>') : c.muted(' Nenhum estilo salvo ainda. /taste salvar <nome> guarda o gosto de agora.'));
|
|
2237
|
+
break;
|
|
2238
|
+
} else if (/^tirar\s+\d+$/.test(a)) {
|
|
2239
|
+
const g = G.tirarReferencia(a.split(/\s+/)[1]);
|
|
2240
|
+
console.log(g ? c.ok(` Referência ${a.split(/\s+/)[1]} tirada.`) : c.err(' Não tem essa referência. /taste mostra os números.'));
|
|
2241
|
+
} else if (a && a !== 'ver') { console.log(c.err('Uso: /taste [refazer|apagar|tirar N|força pouco/médio/muito|provar [assunto]|salvar <nome>|usar <nome>|estilos]')); break; }
|
|
2242
|
+
const linhas = G.listar(G.ler());
|
|
2243
|
+
if (!linhas.length) { console.log(c.muted(' Ainda não tem gosto salvo. /taste refazer abre a tela, e /taste referencias recebe os vídeos que você curtiu.')); break; }
|
|
2244
|
+
for (const l of linhas) console.log(/^\s*"/.test(l) ? c.muted(' ' + l) : ' ' + l);
|
|
2245
|
+
if ((G.ler().referencias || []).length) console.log(c.muted(' /taste tirar N tira um vídeo · /taste referencias traz mais'));
|
|
2246
|
+
break;
|
|
2247
|
+
}
|
|
2248
|
+
/* A memória entre sessões (lib/memoria-usuario.js): ver, esquecer, achar a pasta. */
|
|
2249
|
+
case 'memory': {
|
|
2250
|
+
const M = require('../memoria-usuario.js');
|
|
2251
|
+
const [sub, ...resto] = String(rest || '').trim().split(/\s+/);
|
|
2252
|
+
const a = (sub || '').toLowerCase();
|
|
2253
|
+
if (a === 'pasta') { console.log(c.muted(' ') + M.pasta()); break; }
|
|
2254
|
+
if (a === 'esquecer') {
|
|
2255
|
+
const alvo = resto.join(' ');
|
|
2256
|
+
if (!alvo) { console.log(c.err('Uso: /memory esquecer <nome>')); break; }
|
|
2257
|
+
const r = M.apagar(alvo);
|
|
2258
|
+
console.log(r.ok ? c.ok(` Esqueci "${r.nome}".`) : c.err(' ' + r.error));
|
|
2259
|
+
break;
|
|
2260
|
+
}
|
|
2261
|
+
if (a) { console.log(c.err('Uso: /memory [esquecer <nome> | pasta]')); break; }
|
|
2262
|
+
const lista = M.listar();
|
|
2263
|
+
if (!lista.length) { console.log(c.muted(' Ainda não lembro de nada. Conforme você trabalha, eu vou anotando.')); break; }
|
|
2264
|
+
console.log('');
|
|
2265
|
+
for (const m of lista) console.log(' ' + c.brand(m.nome) + c.dim(` (${m.tipo})`) + c.muted(' — ' + m.descricao));
|
|
2266
|
+
console.log(c.dim(`\n ${lista.length} memórias · /memory esquecer <nome> · /memory pasta`));
|
|
2267
|
+
break;
|
|
2268
|
+
}
|
|
2269
|
+
case 'sandbox': {
|
|
2270
|
+
const sb = require('../permission/sandbox.js');
|
|
2271
|
+
const [a, b] = String(rest || '').toLowerCase().split(/\s+/);
|
|
2272
|
+
if (a === 'on' || a === 'off') sb.salvar({ ligado: a === 'on' });
|
|
2273
|
+
else if (a === 'rede' && (b === 'on' || b === 'off')) sb.salvar({ rede: b === 'on' });
|
|
2274
|
+
else if (a === 'ssh' && (b === 'on' || b === 'off')) sb.salvar({ ssh_agent: b === 'on' });
|
|
2275
|
+
else if (a && a !== 'status') { console.log(c.err('Uso: /sandbox [on|off|rede on|rede off|ssh on|ssh off|status]')); break; }
|
|
2276
|
+
const e = sb.estado();
|
|
2277
|
+
console.log(c.muted(' Sandbox: ') + (e.ativo ? c.ok('ligado') : c.warn(e.ligado ? 'ligado, mas sem mecanismo neste computador' : 'desligado'))
|
|
2278
|
+
+ c.muted(` · mecanismo: ${e.mecanismo || 'nenhum'} · rede: ${e.rede ? 'aberta' : 'bloqueada'} · ssh-agent: ${e.ssh_agent ? 'liberado' : 'fora'} · modo: ${e.modo}`));
|
|
2279
|
+
console.log(c.dim(' Escreve só no projeto, /tmp e ~/.primocode/cache; não lê ~/.ssh, ~/.aws, ~/.npmrc, a sua conta do PrimoCode e outros arquivos de credencial, nem .env*.'));
|
|
2280
|
+
console.log(c.dim(` ${e.rede ? 'Com a rede aberta, o que o comando LÊ pode sair pela internet: a lista acima é o que fica protegido. ' : ''}Detalhes: docs/sandbox.md`));
|
|
2281
|
+
break;
|
|
2282
|
+
}
|
|
2283
|
+
case 'perms': {
|
|
2284
|
+
const DIZ = {
|
|
2285
|
+
auto: 'roda tudo, mas pergunta antes do que não tem volta (apagar fora do projeto, push --force, sudo…)',
|
|
2286
|
+
perguntar: 'pergunta antes de todo comando e de toda escrita de arquivo',
|
|
2287
|
+
livre: 'nunca pergunta — nem antes do que não tem volta',
|
|
2288
|
+
plano: 'só lê: recusa escrita e comando que muda coisa; investiga e entrega o plano',
|
|
2289
|
+
};
|
|
2290
|
+
const atual = perigo.normalizarModo(state.config.permissoes);
|
|
2291
|
+
if (!rest) {
|
|
2292
|
+
console.log(c.muted(' Agora: ') + c.brand(atual) + c.muted(' — ' + DIZ[atual]));
|
|
2293
|
+
for (const m of perigo.MODOS) console.log(` ${m === atual ? c.brand('● ' + m) : c.muted('○ ' + m)} ${c.dim(DIZ[m])}`);
|
|
2294
|
+
console.log(c.dim(' Use /perms auto|perguntar|livre|plano'));
|
|
2295
|
+
break;
|
|
2296
|
+
}
|
|
2297
|
+
const pedido = rest.toLowerCase();
|
|
2298
|
+
if (!perigo.MODOS.includes(perigo.normalizarModo(pedido)) || (perigo.normalizarModo(pedido) === 'auto' && pedido !== 'auto')) {
|
|
2299
|
+
console.log(c.err('Uso: /perms auto|perguntar|livre|plano'));
|
|
2300
|
+
break;
|
|
2301
|
+
}
|
|
2302
|
+
const m = perigo.normalizarModo(pedido);
|
|
2303
|
+
state.config.permissoes = m;
|
|
2304
|
+
cfg.saveConfig({ permissoes: m });
|
|
2305
|
+
console.log(c.ok(` Permissões: ${m}`) + c.muted(' — ' + DIZ[m]));
|
|
2306
|
+
if (m === 'livre') {
|
|
2307
|
+
console.log(' ' + c.warn('▸▸ Atenção: ele vai apagar, forçar push e usar sudo sem te perguntar.'));
|
|
2308
|
+
console.log(' ' + c.warn(' O que der errado pode não ter volta. /perms auto desfaz.'));
|
|
2309
|
+
}
|
|
2310
|
+
break;
|
|
2311
|
+
}
|
|
2312
|
+
|
|
2313
|
+
case 'mode': {
|
|
2314
|
+
const m = rest.toLowerCase();
|
|
2315
|
+
if (['primocode', 'chat', 'auto'].includes(m)) {
|
|
2316
|
+
state.mode = m;
|
|
2317
|
+
state.modoEfetivo = null;
|
|
2318
|
+
cfg.saveConfig({ mode: m });
|
|
2319
|
+
console.log(c.ok(`Modo: ${m}`) + (m === 'auto'
|
|
2320
|
+
? c.muted(' — escolho por pedido: conversa vai pro chat, tarefa vai pro agente')
|
|
2321
|
+
: ''));
|
|
2322
|
+
refreshPrompt();
|
|
2323
|
+
} else console.log(c.err('Uso: /mode primocode|chat|auto'));
|
|
2324
|
+
break;
|
|
2325
|
+
}
|
|
2326
|
+
|
|
2327
|
+
// O /model virou /effort: você escolhe o ESFORÇO num slider (←/→,
|
|
2328
|
+
// Enter confirma, Esc cancela) e o modelo sai daí. Com argumento
|
|
2329
|
+
// ("/effort high") aplica direto, para quem já sabe o que quer.
|
|
2330
|
+
case 'effort': {
|
|
2331
|
+
const pedido = rest.toLowerCase().trim();
|
|
2332
|
+
if (pedido) {
|
|
2333
|
+
if (!effort.NOMES.includes(pedido)) {
|
|
2334
|
+
console.log(c.err(`Esforço inválido. Use: ${effort.NOMES.join(' | ')}`));
|
|
2335
|
+
break;
|
|
2336
|
+
}
|
|
2337
|
+
aplicarEffort(pedido);
|
|
2338
|
+
break;
|
|
2339
|
+
}
|
|
2340
|
+
const escolhido = await sliderEffort(state.config.effort);
|
|
2341
|
+
if (escolhido) aplicarEffort(escolhido);
|
|
2342
|
+
else console.log(c.muted(' Nada mudou.'));
|
|
2343
|
+
break;
|
|
2344
|
+
}
|
|
2345
|
+
|
|
2346
|
+
// Continua existindo para quem fixa um ID do OpenRouter na unha; o
|
|
2347
|
+
// caminho normal é o /effort.
|
|
2348
|
+
case 'model': {
|
|
2349
|
+
const m = rest.toLowerCase();
|
|
2350
|
+
if (m.includes('/')) {
|
|
2351
|
+
state.config.model = m;
|
|
2352
|
+
cfg.saveConfig({ model: m });
|
|
2353
|
+
console.log(c.ok(`Modelo fixo: ${m}`) + c.muted(' precisa aceitar tools no modo primocode'));
|
|
2354
|
+
console.log(c.dim(' Para voltar ao normal, use /effort.'));
|
|
2355
|
+
} else {
|
|
2356
|
+
console.log(c.muted(' O modelo agora vem do esforço. Use ') + c.brand('/effort') + c.muted('.'));
|
|
2357
|
+
console.log(c.dim(` Agora: ${state.config.effort} → modelo ${effort.modeloDe(state.config.effort)}`));
|
|
2358
|
+
}
|
|
2359
|
+
break;
|
|
2360
|
+
}
|
|
2361
|
+
|
|
2362
|
+
case 'attach': {
|
|
2363
|
+
if (!rest) { listarAnexos(); break; }
|
|
2364
|
+
if (/^https?:\/\//i.test(rest)) { await anexarPagina(rest); break; }
|
|
2365
|
+
try {
|
|
2366
|
+
// Relativo à pasta de trabalho (a do /dir), como o /read — não ao
|
|
2367
|
+
// terminal de onde o PrimoCode foi aberto.
|
|
2368
|
+
const content = fs.readFileSync(path.resolve(projectDir(), rest), 'utf-8');
|
|
2369
|
+
state.attachedFiles.push({ path: rest, content });
|
|
2370
|
+
console.log(c.ok(`Anexado: ${rest} (${tools.fmtBytes(content.length)})`));
|
|
2371
|
+
refreshPrompt();
|
|
2372
|
+
} catch { console.log(c.err(`Não consegui ler: ${rest}`)); }
|
|
2373
|
+
break;
|
|
2374
|
+
}
|
|
2375
|
+
|
|
2376
|
+
case 'init': {
|
|
2377
|
+
const alvo = path.join(projectDir(), 'PRIMO.md');
|
|
2378
|
+
if (fs.existsSync(alvo) && !(await confirm(`Já existe um PRIMO.md em ${shortPath(projectDir())}. Escrever outro por cima?`))) {
|
|
2379
|
+
console.log(c.muted(' Deixei o PRIMO.md como estava.'));
|
|
2380
|
+
break;
|
|
2381
|
+
}
|
|
2382
|
+
// Escrever arquivo pede o agente: no modo chat (ou num auto que
|
|
2383
|
+
// achasse que é conversa) o /init só responderia um texto.
|
|
2384
|
+
const modoAntes = state.mode;
|
|
2385
|
+
state.mode = 'primocode';
|
|
2386
|
+
// o /init reescreve o PRIMO.md inteiro: as regras do /regra voltam pro topo depois
|
|
2387
|
+
const regras = require('../regras.js');
|
|
2388
|
+
const guardadas = regras.ler(projectDir());
|
|
2389
|
+
try { await sendPrompt(PEDIDO_INIT); } finally {
|
|
2390
|
+
state.mode = modoAntes;
|
|
2391
|
+
if (regras.garantir(projectDir(), guardadas).length) console.log(c.muted(` As suas ${guardadas.length === 1 ? 'regra voltou' : guardadas.length + ' regras voltaram'} pro topo do PRIMO.md.`));
|
|
2392
|
+
}
|
|
2393
|
+
break;
|
|
2394
|
+
}
|
|
2395
|
+
|
|
2396
|
+
case 'detach': state.attachedFiles = []; console.log(c.ok('Anexos removidos.')); refreshPrompt(); break;
|
|
2397
|
+
|
|
2398
|
+
|
|
2399
|
+
// A lista vem de lib/skill/catalogo.js, e o test/catalogo.test.js cruza aquela
|
|
2400
|
+
// lista com as tools que o tools.execute realmente atende. Ou seja: esta
|
|
2401
|
+
// tela não consegue prometer coisa que o programa não faz.
|
|
2402
|
+
|
|
2403
|
+
/* ── /desfazer ────────────────────────────────────────────────
|
|
2404
|
+
* Quem não sabe git não tem como voltar uma edição ruim. Aqui volta:
|
|
2405
|
+
* cada pedido tirou uma foto do projeto (com git) ou guardou o
|
|
2406
|
+
* original dos arquivos que mexeu (sem git). */
|
|
2407
|
+
case 'undo': {
|
|
2408
|
+
const cps = checkpoint.lista(projectDir());
|
|
2409
|
+
const BK = require('../backup-banco.js');
|
|
2410
|
+
const hora = (iso) => new Date(iso).toLocaleString('pt-BR', { dateStyle: 'short', timeStyle: 'short' });
|
|
2411
|
+
if (!cps.length) {
|
|
2412
|
+
// sem foto do pedido (a pasta está fora do git, ou o banco é ignorado), a cópia do banco ainda volta
|
|
2413
|
+
const sobra = BK.pendentes(projectDir()).slice(-1)[0];
|
|
2414
|
+
if (!sobra) { console.log(c.muted(' Nada para desfazer nesta pasta.')); break; }
|
|
2415
|
+
console.log(c.muted(` Tem uma cópia do banco de ${hora(sobra.criado)}: ${sobra.arquivos.join(', ')}`));
|
|
2416
|
+
if (!(await confirm('Voltar o banco para essa cópia?'))) { console.log(c.muted('Cancelado.')); break; }
|
|
2417
|
+
for (const f of BK.restaurar(projectDir(), sobra)) console.log(f.acao === 'falhou' ? c.err(` falhou: ${f.erro} ${f.arquivo}`) : c.ok(' banco voltou ') + f.arquivo);
|
|
2418
|
+
break;
|
|
2419
|
+
}
|
|
2420
|
+
const quando = (cp) => new Date(cp.quando).toLocaleString('pt-BR', { dateStyle: 'short', timeStyle: 'short' });
|
|
2421
|
+
if (/^(lista|list|ls)$/i.test(rest)) {
|
|
2422
|
+
cps.forEach((cp, i) => console.log(` ${c.brand(String(i + 1).padStart(2))} ${c.dim(quando(cp))} `
|
|
2423
|
+
+ `${c.white(cp.pedido.slice(0, 50) + (cp.pedido.length > 50 ? '…' : ''))} `
|
|
2424
|
+
+ c.muted(`${cp.mudou.length} ${cp.mudou.length === 1 ? 'arquivo mudou' : 'arquivos mudaram'}`)
|
|
2425
|
+
+ (cp.funcionava ? ` ${c.ok('✓ funcionava')}${cp.funcionava_como ? c.dim(' · ' + cp.funcionava_como) : ''}` : '')));
|
|
2426
|
+
console.log(c.muted('\n /undo N volta os N últimos pedidos.'));
|
|
2427
|
+
if (checkpoint.modo(projectDir()) === 'arquivo') {
|
|
2428
|
+
console.log(c.muted(' Sem git aqui: só volta o que o agente escreveu com as ferramentas de arquivo (não o que um comando apagou).'));
|
|
2429
|
+
}
|
|
2430
|
+
break;
|
|
2431
|
+
}
|
|
2432
|
+
// /desfazer fora: só o que o último pedido mudou sem você ter citado (lib/escopo.js)
|
|
2433
|
+
if (/^(fora|extras?)$/i.test(rest)) {
|
|
2434
|
+
// tirado do checkpoint (o pedido fica no manifest), não da memória: vale depois de fechar e abrir o PrimoCode
|
|
2435
|
+
const ultimo = cps[0];
|
|
2436
|
+
const fora = ultimo ? require('../escopo.js').foraDoPedido(ultimo.pedido, ultimo.mudou, projectDir()) : [];
|
|
2437
|
+
if (!fora.length) { console.log(c.muted(' O último pedido não mexeu em nada além do que você citou.')); break; }
|
|
2438
|
+
const feitos = checkpoint.desfazerArquivos(projectDir(), fora.map((f) => f.caminho));
|
|
2439
|
+
for (const f of feitos) console.log(f.acao === 'falhou' ? c.err(` ✗ ${shortPath(f.caminho)}: ${f.erro}`) : c.ok(` ↺ ${path.relative(projectDir(), f.caminho)}`) + c.dim(` (${f.acao})`));
|
|
2440
|
+
console.log(c.muted(' O que você pediu ficou. /undo volta o pedido inteiro.'));
|
|
2441
|
+
break;
|
|
2442
|
+
}
|
|
2443
|
+
const n = rest ? parseInt(rest, 10) : 1;
|
|
2444
|
+
if (!(n >= 1)) { console.log(c.err('Uso: /undo · /undo lista · /undo N · /undo fora')); break; }
|
|
2445
|
+
const alvo = cps.slice(0, n);
|
|
2446
|
+
console.log(c.muted(`\n Volta ${alvo.length === 1 ? 'o último pedido' : `os ${alvo.length} últimos pedidos`}:`));
|
|
2447
|
+
for (const cp of alvo) console.log(` ${c.dim(quando(cp))} ${c.white(cp.pedido.slice(0, 60))}`);
|
|
2448
|
+
const previa = checkpoint.previa(projectDir(), n);
|
|
2449
|
+
if (!previa.length) console.log(c.muted(' (o disco já está como estava antes)'));
|
|
2450
|
+
for (const a of previa.slice(0, 40)) console.log(c.muted(` ${a.acao} `) + shortPath(a.caminho));
|
|
2451
|
+
if (previa.length > 40) console.log(c.muted(` … e mais ${previa.length - 40}`));
|
|
2452
|
+
// a cópia do banco feita durante esses pedidos: a MAIS VELHA é o banco de antes de tudo
|
|
2453
|
+
const copiaDoBanco = BK.desde(projectDir(), alvo[alvo.length - 1].quando).slice(-1)[0];
|
|
2454
|
+
if (copiaDoBanco) console.log(c.muted(' banco ') + `volta pra cópia de ${hora(copiaDoBanco.criado)} (${copiaDoBanco.arquivos.join(', ')})`);
|
|
2455
|
+
if (!(await confirm('Desfazer?'))) { console.log(c.muted('Cancelado.')); break; }
|
|
2456
|
+
try { require('../placar.js').desfez(); } catch { /* placar é conveniência */ } // desfez logo depois do pedido: conta como perda do modelo
|
|
2457
|
+
for (const f of checkpoint.desfazer(projectDir(), n)) {
|
|
2458
|
+
const rotulo = f.acao === 'falhou' ? c.err(` falhou: ${f.erro} `) : c.ok(` ${f.acao} `);
|
|
2459
|
+
console.log(rotulo + shortPath(f.caminho));
|
|
2460
|
+
}
|
|
2461
|
+
if (copiaDoBanco) for (const f of BK.restaurar(projectDir(), copiaDoBanco)) console.log(f.acao === 'falhou' ? c.err(` falhou: ${f.erro} ${f.arquivo}`) : c.ok(' banco voltou ') + f.arquivo);
|
|
2462
|
+
if (checkpoint.refazerDisponivel(projectDir())) console.log(c.muted('\n Mudou de ideia? ') + c.brand('/redo') + c.muted(' devolve.'));
|
|
2463
|
+
break;
|
|
2464
|
+
}
|
|
2465
|
+
|
|
2466
|
+
/* /refazer: o arrependimento do /desfazer. Só o último, e só enquanto
|
|
2467
|
+
nenhum pedido novo mexeu nos arquivos (lib/session/checkpoint.js). */
|
|
2468
|
+
case 'redo': {
|
|
2469
|
+
const volta = checkpoint.refazerDisponivel(projectDir());
|
|
2470
|
+
if (!volta) { console.log(c.muted(' Nada para refazer: o /redo só volta o último /undo, antes de um pedido novo mudar os arquivos.')); break; }
|
|
2471
|
+
console.log(c.muted(`\n Refaz ${volta.pedidos.length === 1 ? 'o pedido' : `os ${volta.pedidos.length} pedidos`}:`));
|
|
2472
|
+
for (const p of volta.pedidos) console.log(` ${c.white(String(p || '').slice(0, 60))}`);
|
|
2473
|
+
if (!(await confirm('Refazer?'))) { console.log(c.muted('Cancelado.')); break; }
|
|
2474
|
+
for (const f of checkpoint.refazer(projectDir())) {
|
|
2475
|
+
const rotulo = f.acao === 'falhou' ? c.err(` falhou: ${f.erro} `) : c.ok(` ${f.acao} `);
|
|
2476
|
+
console.log(rotulo + shortPath(f.caminho));
|
|
2477
|
+
}
|
|
2478
|
+
break;
|
|
2479
|
+
}
|
|
2480
|
+
|
|
2481
|
+
/* /conferir: "funcionou / não funcionou" em português simples. Passou?
|
|
2482
|
+
O ponto fica marcado e o /restore sabe para onde ir. Falhou? Oferece
|
|
2483
|
+
a IA consertar com a saída do erro já na mão. */
|
|
2484
|
+
case 'check': {
|
|
2485
|
+
const achou = conferirLib.descobrir(projectDir());
|
|
2486
|
+
if (!achou && require('../pipeline.js').acharEntrada(projectDir())) {
|
|
2487
|
+
// sem script de teste, mas é uma página: abrir escondido e olhar é o teste que existe
|
|
2488
|
+
const spP = new Spinner('abrindo a página escondido pra conferir').start();
|
|
2489
|
+
let m = null;
|
|
2490
|
+
try { m = await require('../pipeline.js').medirNoNavegador(projectDir()); } catch (e) { m = { testou: false, relato: e.message }; }
|
|
2491
|
+
spP.stop();
|
|
2492
|
+
const exP = conferirLib.explicarPagina(m);
|
|
2493
|
+
if (exP.ok) {
|
|
2494
|
+
console.log(c.ok(` ✓ ${exP.titulo}`));
|
|
2495
|
+
if (checkpoint.marcarFuncionando(projectDir(), 'a página abriu sem erro')) console.log(c.muted(" Marquei este ponto como 'funcionava': /restore volta pra cá, e a /timeline mostra."));
|
|
2496
|
+
break;
|
|
2497
|
+
}
|
|
2498
|
+
console.log((exP.testou ? c.err : c.warn)(` ${exP.testou ? '✗' : '·'} ${exP.titulo}`));
|
|
2499
|
+
for (const l of exP.linhas) console.log(c.muted(` ${l}`));
|
|
2500
|
+
if (exP.testou && await confirm('Quero que a IA conserte?')) {
|
|
2501
|
+
await sendPrompt(`Abri a página escondido e ela tem problema:\n${m.relato}\nAche a causa, conserte e confira de novo.`);
|
|
2502
|
+
}
|
|
2503
|
+
break;
|
|
2504
|
+
}
|
|
2505
|
+
if (!achou) { console.log(c.muted(" Não achei como testar este projeto (sem script de test/build, e sem página pra abrir). Peça: 'cria testes pra isso'.")); break; }
|
|
2506
|
+
console.log(c.muted(` $ ${achou.comando}`));
|
|
2507
|
+
const sp = new Spinner(`rodando ${achou.rotulo}`).start();
|
|
2508
|
+
const r = await conferirLib.rodar(achou.comando, projectDir());
|
|
2509
|
+
sp.stop();
|
|
2510
|
+
if (r.semTeste) { console.log(c.muted(` O ${achou.comando} não achou teste pra rodar (ou o pytest não está instalado). Peça: 'cria testes pra isso'.`)); break; }
|
|
2511
|
+
const ex = conferirLib.explicar(r, achou);
|
|
2512
|
+
if (r.ok) {
|
|
2513
|
+
console.log(c.ok(` ✓ ${ex.titulo}`));
|
|
2514
|
+
if (checkpoint.marcarFuncionando(projectDir(), achou.comando)) {
|
|
2515
|
+
console.log(c.muted(" Marquei este ponto como 'funcionava': /restore volta pra cá, e a /timeline mostra."));
|
|
2516
|
+
} else {
|
|
2517
|
+
// sem pedido nenhum nesta pasta ainda, não há ponto pra marcar: dizer, em vez de calar
|
|
2518
|
+
console.log(c.muted(' Ainda não tem ponto pra marcar: o primeiro pedido que mexer nos arquivos cria um, e o próximo /check marca.'));
|
|
2519
|
+
}
|
|
2520
|
+
break;
|
|
2521
|
+
}
|
|
2522
|
+
console.log(c.err(` ✗ ${ex.titulo}`));
|
|
2523
|
+
for (const l of ex.linhas) console.log(c.muted(` ${l}`));
|
|
2524
|
+
if (await confirm('Quero que a IA conserte?')) {
|
|
2525
|
+
await sendPrompt(`Rodei \`${achou.comando}\` e falhou. A saída:\n${r.saida}\nAche a causa, conserte e rode \`${achou.comando}\` de novo até passar.`);
|
|
2526
|
+
}
|
|
2527
|
+
break;
|
|
2528
|
+
}
|
|
2529
|
+
|
|
2530
|
+
/* /voltar: o /desfazer com destino certo — o último ponto que o
|
|
2531
|
+
/check marcou como funcionando, em vez de "N pedidos" no chute. */
|
|
2532
|
+
case 'restore': {
|
|
2533
|
+
const ponto = checkpoint.ultimoQueFuncionava(projectDir());
|
|
2534
|
+
if (!ponto) { console.log(c.muted(' Nenhum ponto marcado ainda. Quando estiver funcionando, rode /check: ele marca.')); break; }
|
|
2535
|
+
if (ponto.indice === 0) { console.log(c.muted(' Você já está no último ponto que funcionava.')); break; }
|
|
2536
|
+
const quando = (cp) => new Date(cp.quando).toLocaleString('pt-BR', { dateStyle: 'short', timeStyle: 'short' });
|
|
2537
|
+
const alvo = checkpoint.lista(projectDir()).slice(0, ponto.indice);
|
|
2538
|
+
console.log(c.muted(`\n O último ponto que funcionava: ${quando(ponto.cp)}, "${String(ponto.cp.pedido || '').slice(0, 50)}"`)
|
|
2539
|
+
+ (ponto.cp.funcionava_como ? c.dim(` (conferido: ${ponto.cp.funcionava_como})`) : ''));
|
|
2540
|
+
console.log(c.muted(`\n Volta ${alvo.length === 1 ? 'o pedido' : `os ${alvo.length} pedidos`} feito${alvo.length === 1 ? '' : 's'} depois do último ponto que funcionava:`));
|
|
2541
|
+
for (const cp of alvo) console.log(` ${c.dim(quando(cp))} ${c.white(cp.pedido.slice(0, 60))}`);
|
|
2542
|
+
const previa = checkpoint.previa(projectDir(), ponto.indice);
|
|
2543
|
+
if (!previa.length) console.log(c.muted(' (o disco já está como estava antes)'));
|
|
2544
|
+
for (const a of previa.slice(0, 40)) console.log(c.muted(` ${a.acao} `) + shortPath(a.caminho));
|
|
2545
|
+
if (previa.length > 40) console.log(c.muted(` … e mais ${previa.length - 40}`));
|
|
2546
|
+
if (!(await confirm('Voltar?'))) { console.log(c.muted('Cancelado.')); break; }
|
|
2547
|
+
for (const f of checkpoint.desfazer(projectDir(), ponto.indice)) {
|
|
2548
|
+
const rotulo = f.acao === 'falhou' ? c.err(` falhou: ${f.erro} `) : c.ok(` ${f.acao} `);
|
|
2549
|
+
console.log(rotulo + shortPath(f.caminho));
|
|
2550
|
+
}
|
|
2551
|
+
if (checkpoint.refazerDisponivel(projectDir())) console.log(c.muted('\n Mudou de ideia? ') + c.brand('/redo') + c.muted(' devolve.'));
|
|
2552
|
+
console.log(c.muted(' A história inteira do projeto, numa página: ') + c.brand('/timeline'));
|
|
2553
|
+
break;
|
|
2554
|
+
}
|
|
2555
|
+
|
|
2556
|
+
/* /linha-do-tempo: o /desfazer lista numa página que quem não sabe
|
|
2557
|
+
git consegue ler. Pedido explícito, então abre o navegador; se não
|
|
2558
|
+
abrir (app de voz), mostra onde o arquivo ficou. */
|
|
2559
|
+
/* /mostrar: o app no celular de alguém no mesmo Wi-Fi, com link de prazo, sem publicar (lib/mostrar.js). */
|
|
2560
|
+
case 'show': {
|
|
2561
|
+
const arg = String(rest || '').trim().toLowerCase();
|
|
2562
|
+
if (state.mostrando && (arg === 'parar' || arg === 'stop')) { await state.mostrando.fechar(); state.mostrando = null; console.log(c.ok(' Parei de mostrar. O link não abre mais.')); break; }
|
|
2563
|
+
if (arg === 'parar' || arg === 'stop') { console.log(c.muted(' Não estou mostrando nada agora.')); break; }
|
|
2564
|
+
const entradaMostrar = require('../pipeline.js').acharEntrada(projectDir());
|
|
2565
|
+
if (!entradaMostrar) { console.log(c.muted(' Não achei uma página pra mostrar (um index.html). Esse projeto roda como servidor? Peça "roda o projeto".')); break; }
|
|
2566
|
+
if (state.mostrando) await state.mostrando.fechar();
|
|
2567
|
+
const minutos = Math.max(5, Math.min(240, Number(arg) || 60));
|
|
2568
|
+
const r = await require('../mostrar.js').abrir(projectDir(), { minutos, entrada: entradaMostrar }); // lista.html sem index.html também abre
|
|
2569
|
+
if (!r.ok) { console.log(c.err(` Não consegui abrir: ${r.error}`)); break; }
|
|
2570
|
+
state.mostrando = r;
|
|
2571
|
+
console.log(c.ok(` Mostrando ${path.basename(projectDir())} por ${minutos} min, só pra quem está no mesmo Wi-Fi:`));
|
|
2572
|
+
console.log(' ' + c.white(r.url || r.urlLocal));
|
|
2573
|
+
console.log(c.muted(' Nada foi publicado: o link morre no prazo ou quando você fecha o PrimoCode. .env, .git e node_modules nunca saem. /show parar fecha agora.'));
|
|
2574
|
+
break;
|
|
2575
|
+
}
|
|
2576
|
+
/* /como-rodar: o bloco "Como rodar" do PRIMO.md, tirado do disco sem modelo (lib/como-rodar.js). */
|
|
2577
|
+
case 'howto': {
|
|
2578
|
+
const r = require('../como-rodar.js').gravar(projectDir());
|
|
2579
|
+
if (!r.passos.length) { console.log(c.muted(' Ainda não deu pra saber como este projeto roda (sem package.json, index.html nem main.py).')); break; }
|
|
2580
|
+
console.log(c.ok(` ${r.criou ? 'Criei o PRIMO.md' : 'Atualizei o PRIMO.md'} com o "Como rodar":`));
|
|
2581
|
+
r.passos.forEach((p, i) => console.log(` ${c.brand(String(i + 1))} ${p.texto}${p.comando ? c.muted(': ') + c.white(p.comando) : ''}`));
|
|
2582
|
+
console.log(c.muted(' O PrimoCode lê o PRIMO.md em todo pedido. Rodar de novo atualiza o bloco.'));
|
|
2583
|
+
break;
|
|
2584
|
+
}
|
|
2585
|
+
/* /porta: "o app não abre" por causa da porta, dito em português (lib/porta.js). */
|
|
2586
|
+
case 'port': {
|
|
2587
|
+
const r = await require('../porta.js').diagnostico(projectDir());
|
|
2588
|
+
r.linhas.forEach((l, i) => console.log(i === 0 ? ' ' + (r.url ? c.ok(l) : c.warn(l)) : /^Abra:|abra: http/.test(l) ? ' ' + c.white(l) : c.muted(' ' + l)));
|
|
2589
|
+
if (r.url) console.log(c.muted(` /open ${r.url} abre no navegador.`));
|
|
2590
|
+
break;
|
|
2591
|
+
}
|
|
2592
|
+
/* /regra: "nunca mexa em X" no topo do PRIMO.md, que entra em todo pedido e não vira resumo (lib/regras.js). */
|
|
2593
|
+
case 'rule': {
|
|
2594
|
+
const R = require('../regras.js');
|
|
2595
|
+
const mostrar = (lista) => lista.forEach((r, i) => console.log(` ${c.brand(String(i + 1))} ${r}`));
|
|
2596
|
+
const tira = rest.match(/^(?:tirar|tira|apagar|remover)\s+(\d+)$/i);
|
|
2597
|
+
if (tira) {
|
|
2598
|
+
const r = R.tirar(projectDir(), tira[1]);
|
|
2599
|
+
if (!r) { console.log(c.err(` Não tem regra ${tira[1]}. /rule mostra a lista.`)); break; }
|
|
2600
|
+
console.log(c.ok(` Tirei: ${r.tirada}`));
|
|
2601
|
+
if (r.regras.length) mostrar(r.regras); else console.log(c.muted(' Não sobrou nenhuma regra.'));
|
|
2602
|
+
break;
|
|
2603
|
+
}
|
|
2604
|
+
if (!rest.trim()) {
|
|
2605
|
+
const lista = R.ler(projectDir());
|
|
2606
|
+
if (!lista.length) { console.log(c.muted(' Nenhuma regra ainda. Exemplo: /rule nunca mexa no style.css')); break; }
|
|
2607
|
+
console.log(c.white(` As regras de ${path.basename(projectDir())} (o PrimoCode segue em todo pedido):`));
|
|
2608
|
+
mostrar(lista);
|
|
2609
|
+
console.log(c.muted(' /rule tirar N tira uma.'));
|
|
2610
|
+
break;
|
|
2611
|
+
}
|
|
2612
|
+
const r = R.adicionar(projectDir(), rest);
|
|
2613
|
+
console.log(r.ja_tinha ? c.muted(' Essa regra já estava lá.') : c.ok(' Guardei no topo do PRIMO.md. Vale em todo pedido, mesmo depois de resumir a conversa:'));
|
|
2614
|
+
mostrar(r.regras);
|
|
2615
|
+
break;
|
|
2616
|
+
}
|
|
2617
|
+
/* /mapa: o que tem no projeto, em português, e o arquivo que é pedido mas não existe (lib/mapa.js). */
|
|
2618
|
+
case 'map': {
|
|
2619
|
+
const arvore = rest.match(/^(?:tree|arvore|árvore)\b\s*(\d*)/i);
|
|
2620
|
+
if (arvore) { console.log(tools.treeDir(projectDir(), parseInt(arvore[1], 10) || 2)); break; }
|
|
2621
|
+
const M = require('../mapa.js');
|
|
2622
|
+
const m = M.montar(projectDir());
|
|
2623
|
+
for (const l of M.texto(m, path.basename(projectDir()))) console.log(/⚠/.test(l) ? c.warn(l) : /^\S/.test(l) ? ' ' + c.white(l) : c.muted(l));
|
|
2624
|
+
if (m.faltando.length) console.log(c.muted(' Peça: "cria o que está faltando", ou rode /check pra ver a página abrindo.'));
|
|
2625
|
+
break;
|
|
2626
|
+
}
|
|
2627
|
+
/* /mudou: o que mudou no projeto, em português simples (lib/mudou.js), e não um diff. */
|
|
2628
|
+
case 'changes': {
|
|
2629
|
+
const r = require('../mudou.js').medir(projectDir());
|
|
2630
|
+
console.log(' ' + c.white(r.frase));
|
|
2631
|
+
for (const a of r.arquivos.slice(0, 15)) {
|
|
2632
|
+
const rotulo = r.git ? (a.novo ? c.ok('novo ') : a.apagado ? c.warn('apagado ') : c.muted('editado ')) : c.muted((a.acao || 'mudou').padEnd(8));
|
|
2633
|
+
const conta = r.git && !a.novo && !a.apagado ? c.dim(` +${a.mais} −${a.menos}`) : '';
|
|
2634
|
+
console.log(` ${rotulo}${a.arquivo}${conta}`);
|
|
2635
|
+
}
|
|
2636
|
+
if (r.arquivos.length > 15) console.log(c.dim(` … e mais ${r.arquivos.length - 15}`));
|
|
2637
|
+
if (r.arquivos.length) console.log(c.muted(' Quebrou algo? /restore volta pro último ponto que funcionava.'));
|
|
2638
|
+
break;
|
|
2639
|
+
}
|
|
2640
|
+
/* /explain: sem nada, o último pedido em 5 linhas; com uma palavra, uma linha; "projeto" é o comando de fábrica. */
|
|
2641
|
+
/* /review: duas passadas (lib/review.js) — achar e depois conferir cada achado. /review rápido = o comando de fábrica de uma passada. */
|
|
2642
|
+
case 'review': {
|
|
2643
|
+
if (/^(r[aá]pido|simples)\b/i.test(rest)) {
|
|
2644
|
+
const fabrica = comandosDaPessoa().find((x) => x.nome === 'review');
|
|
2645
|
+
if (fabrica) { await sendPrompt(comandosLib.expandir(fabrica, rest.replace(/^\S+\s*/, ''))); break; }
|
|
2646
|
+
}
|
|
2647
|
+
const R = require('../review.js');
|
|
2648
|
+
const chamar = async (prompt) => {
|
|
2649
|
+
let resposta = '';
|
|
2650
|
+
await api.requestChat(state.config.server, { prompt, history: [], model: state.config.model, token: state.config.token },
|
|
2651
|
+
(evt) => { if (evt.delta) resposta += evt.delta; });
|
|
2652
|
+
return resposta;
|
|
2653
|
+
};
|
|
2654
|
+
const sp = new Spinner('revisando o que mudou (passada 1: achar)').start();
|
|
2655
|
+
let r;
|
|
2656
|
+
try { r = await R.revisar({ dir: projectDir(), foco: rest, chamar }); } catch (e) { r = { ok: false, erro: String((e && e.message) || e) }; }
|
|
2657
|
+
sp.stop();
|
|
2658
|
+
console.log('\n' + R.formatar(r).split('\n').map((l) => ' ' + l).join('\n') + '\n');
|
|
2659
|
+
break;
|
|
2660
|
+
}
|
|
2661
|
+
case 'explain': {
|
|
2662
|
+
const E = require('../explicar.js');
|
|
2663
|
+
const m = E.modo(rest);
|
|
2664
|
+
if (m.tipo === 'projeto') {
|
|
2665
|
+
const fabrica = comandosDaPessoa().find((x) => x.nome === 'explain');
|
|
2666
|
+
if (!fabrica) { console.log(c.err(' Não achei o comando de fábrica (comandos/explain.md).')); break; }
|
|
2667
|
+
console.log(c.dim(` ⎿ /explain projeto · ${fabrica.origem}`));
|
|
2668
|
+
await sendPrompt(comandosLib.expandir(fabrica, ''));
|
|
2669
|
+
break;
|
|
2670
|
+
}
|
|
2671
|
+
if (m.tipo === 'termo') { await sendPrompt(E.pedidoDoTermo(m.termo)); break; }
|
|
2672
|
+
const ultimo = E.doUltimoPedido(projectDir());
|
|
2673
|
+
if (!ultimo) { console.log(c.muted(' Ainda não mudou nada por aqui. /explain projeto explica o projeto; /explain <palavra> explica uma palavra.')); break; }
|
|
2674
|
+
await sendPrompt(E.pedidoDoUltimo(ultimo));
|
|
2675
|
+
break;
|
|
2676
|
+
}
|
|
2677
|
+
/* /plan: 1ª fase no modo plano (só lê) mostra 3 a 5 passos; Enter começa, um número muda o passo (lib/plano-previo.js). */
|
|
2678
|
+
case 'plan': {
|
|
2679
|
+
const P = require('../plano-previo.js');
|
|
2680
|
+
if (!rest) { console.log(c.muted(' Uso: /plan <pedido> — ele mostra os passos e só começa quando você aperta Enter.')); break; }
|
|
2681
|
+
const antes = state.config.permissoes, tamanho = state.history.length;
|
|
2682
|
+
state.config.permissoes = 'plano';
|
|
2683
|
+
try { await sendPrompt(P.pedidoDoPlano(rest)); } finally { state.config.permissoes = antes; }
|
|
2684
|
+
const ultima = state.history.length > tamanho ? state.history[state.history.length - 1] : null;
|
|
2685
|
+
const passos = ultima && ultima.role === 'assistant' ? P.extrairPassos(ultima.content) : [];
|
|
2686
|
+
if (passos.length < 2) { console.log(c.muted(' Não consegui montar uma lista de passos. Peça de novo, ou mande o pedido sem o /plan.')); break; }
|
|
2687
|
+
for (;;) {
|
|
2688
|
+
console.log(c.white('\n O plano:'));
|
|
2689
|
+
passos.forEach((p, i) => console.log(` ${c.brand(String(i + 1))} ${p}`));
|
|
2690
|
+
const r = P.resposta(await ask(`\n${c.brand('?')} ${c.muted('Enter começa · número muda o passo · n cancela')} `), passos);
|
|
2691
|
+
if (r.acao === 'cancelar') { console.log(c.muted(' Cancelado. Nada foi mexido.')); passos.length = 0; break; }
|
|
2692
|
+
if (r.acao === 'comecar') break;
|
|
2693
|
+
if (r.acao === 'editar') {
|
|
2694
|
+
const novo = (await ask(` ${c.muted(`Passo ${r.n}, com as suas palavras (vazio apaga):`)} `)).trim();
|
|
2695
|
+
if (novo) passos[r.n - 1] = novo; else if (passos.length > 1) passos.splice(r.n - 1, 1);
|
|
2696
|
+
} else console.log(c.muted(' Aperte Enter para começar, digite o número de um passo, ou n.'));
|
|
2697
|
+
}
|
|
2698
|
+
if (!passos.length) break;
|
|
2699
|
+
state.passosProntos = P.comoPassos(rest, passos);
|
|
2700
|
+
try { await sendPrompt(rest); } finally { state.passosProntos = null; }
|
|
2701
|
+
break;
|
|
2702
|
+
}
|
|
2703
|
+
/* /lock: arquivo que o agente só lê. A recusa mora no portão (lib/permission/perigo.js → lib/trava.js). */
|
|
2704
|
+
case 'lock': {
|
|
2705
|
+
const T = require('../trava.js');
|
|
2706
|
+
const palavras = (rest.match(/"[^"]+"|'[^']+'|\S+/g) || []).map((x) => x.replace(/^["']|["']$/g, ''));
|
|
2707
|
+
const lista = (ts) => ts.forEach((t, i) => console.log(` ${c.brand(String(i + 1))} ${t}`));
|
|
2708
|
+
if (/^(off|soltar|solta|destravar|unlock)$/i.test(palavras[0] || '')) {
|
|
2709
|
+
if (palavras.length < 2) { console.log(c.err(' Uso: /lock off <arquivo> (ou /lock off tudo)')); break; }
|
|
2710
|
+
const alvos = palavras.slice(1);
|
|
2711
|
+
for (const a of alvos) {
|
|
2712
|
+
const r = T.soltar(projectDir(), a);
|
|
2713
|
+
console.log(r.soltos.length ? c.ok(` Soltei ${r.soltos.join(', ')}. O agente volta a poder mexer.`) : c.muted(` ${a} não estava travado.`));
|
|
2714
|
+
}
|
|
2715
|
+
break;
|
|
2716
|
+
}
|
|
2717
|
+
if (!palavras.length) {
|
|
2718
|
+
const ts = T.ler(projectDir());
|
|
2719
|
+
if (!ts.length) { console.log(c.muted(' Nenhum arquivo travado. Exemplo: /lock login.js logo.png')); break; }
|
|
2720
|
+
console.log(c.white(` Travados em ${path.basename(projectDir())} (o agente só pode ler):`));
|
|
2721
|
+
lista(ts);
|
|
2722
|
+
console.log(c.muted(' /lock off <arquivo> solta um.'));
|
|
2723
|
+
break;
|
|
2724
|
+
}
|
|
2725
|
+
const r = T.travar(projectDir(), palavras);
|
|
2726
|
+
for (const f of r.fora) console.log(c.warn(` ${f} está fora da pasta do projeto: não travei.`));
|
|
2727
|
+
for (const n of r.novos) if (!fs.existsSync(path.join(projectDir(), n))) console.log(c.muted(` ${n} ainda não existe: travei mesmo assim.`));
|
|
2728
|
+
if (r.novos.length) console.log(c.ok(` Travei ${r.novos.join(', ')}. O agente só pode ler.`));
|
|
2729
|
+
else if (!r.fora.length) console.log(c.muted(' Esses já estavam travados.'));
|
|
2730
|
+
if (r.travados.length) { lista(r.travados); console.log(c.muted(' /lock off <arquivo> solta um.')); }
|
|
2731
|
+
break;
|
|
2732
|
+
}
|
|
2733
|
+
/* /save: guarda o projeto no GitHub, num repositório privado (lib/guardar.js). */
|
|
2734
|
+
case 'save': {
|
|
2735
|
+
const r = require('../guardar.js').salvar(projectDir(), { log: (l) => console.log(c.muted(' ' + l)) });
|
|
2736
|
+
console.log(r.ok ? c.ok(` Seu trabalho está guardado fora do computador: ${r.url}`) : c.warn(` ${r.erro}`));
|
|
2737
|
+
break;
|
|
2738
|
+
}
|
|
2739
|
+
/* /secrets: nomes das chaves, nunca os valores; `add` pede o valor escondido (lib/segredos.js). */
|
|
2740
|
+
case 'secrets': {
|
|
2741
|
+
const S = require('../segredos.js');
|
|
2742
|
+
const [sub, nomeDado] = rest.split(/\s+/).filter(Boolean);
|
|
2743
|
+
if (/^(add|adicionar|novo)$/i.test(sub || '')) {
|
|
2744
|
+
const n = S.nomeValido(nomeDado);
|
|
2745
|
+
if (!n) { console.log(c.warn(' Qual o nome? Exemplo: /secrets add OPENAI_API_KEY')); break; }
|
|
2746
|
+
console.log(c.warn(' Isto é uma chave, não mostre pra ninguém.') + c.muted(' O que você digitar não aparece na tela.'));
|
|
2747
|
+
const valor = (await askSecret(` Valor de ${n}: `)).trim();
|
|
2748
|
+
if (!valor) { console.log(c.muted(' Vazio: não guardei nada.')); break; }
|
|
2749
|
+
try {
|
|
2750
|
+
const r = S.gravar(projectDir(), n, valor);
|
|
2751
|
+
console.log(c.ok(` ${r.substituiu ? 'Troquei' : 'Guardei'} ${n} no .env${r.criou ? ' (criei o arquivo)' : ''}.`));
|
|
2752
|
+
if (r.gitignore) console.log(c.muted(' Pus .env no .gitignore: ele não vai pro GitHub.'));
|
|
2753
|
+
} catch (e) { console.log(c.warn(` ${e.message}`)); }
|
|
2754
|
+
break;
|
|
2755
|
+
}
|
|
2756
|
+
const lista = S.listar(projectDir());
|
|
2757
|
+
if (!lista.length) { console.log(c.muted(' Este projeto não usa nenhuma chave (ainda). Quando precisar: /secrets add NOME')); break; }
|
|
2758
|
+
console.log(c.white(' Chaves deste projeto (só os nomes, nunca o valor):'));
|
|
2759
|
+
for (const x of lista) {
|
|
2760
|
+
const estado = x.noEnv && !x.vazia ? c.ok('guardada') : x.noEnv ? c.warn('vazia no .env') : c.warn('falta guardar');
|
|
2761
|
+
console.log(` ${c.brand(ui.padRight(x.nome, 28))}${ui.padRight(estado, 16)}${c.dim(x.usadaEm.length ? 'usada em ' + x.usadaEm.join(', ') : '')}`);
|
|
2762
|
+
}
|
|
2763
|
+
console.log(c.muted(' /secrets add NOME guarda uma. Isto é uma chave, não mostre pra ninguém.'));
|
|
2764
|
+
break;
|
|
2765
|
+
}
|
|
2766
|
+
case 'testar-app': {
|
|
2767
|
+
const A = require('../plugin/autoteste.js');
|
|
2768
|
+
const r = await A.testar({ dir: projectDir(), log: (l) => console.log(c.muted(' ' + l)), consertar: (erros, prints) => sendPrompt(A.pedidoDeConserto(erros, prints)) });
|
|
2769
|
+
console.log(r.ok ? c.ok(' O app passou no teste.') : c.warn(' ' + r.erro));
|
|
2770
|
+
break;
|
|
2771
|
+
}
|
|
2772
|
+
/* /placar: qual modelo grátis acerta mais em cada tipo de tarefa, neste computador (lib/placar.js). */
|
|
2773
|
+
case 'placar': {
|
|
2774
|
+
const P = require('../placar.js');
|
|
2775
|
+
if (/^(zerar|limpar|reset)$/i.test(rest.trim())) { P.zerar(); console.log(c.ok(' Placar zerado. Ele começa a aprender de novo.')); break; }
|
|
2776
|
+
console.log(P.texto(P.ler()).split('\n').map((l) => ' ' + l.replace(/^ {2}/, '')).join('\n'));
|
|
2777
|
+
break;
|
|
2778
|
+
}
|
|
2779
|
+
case 'pesquisar': {
|
|
2780
|
+
if (!rest) { console.log(c.muted(' Uso: /pesquisar <tema>')); break; }
|
|
2781
|
+
const r = await require('../plugin/pesquisar.js').pesquisar({ tema: rest, dir: projectDir(), log: (l) => console.log(c.muted(' ' + l)) });
|
|
2782
|
+
console.log(r.ok ? c.ok(` Relatório: ${r.arquivo}`) : c.warn(' ' + r.erro));
|
|
2783
|
+
break;
|
|
2784
|
+
}
|
|
2785
|
+
/* /schedule: pedido que roda sozinho no Mac, pelo launchd (lib/agendar.js). */
|
|
2786
|
+
case 'schedule': {
|
|
2787
|
+
const A = require('../agendar.js');
|
|
2788
|
+
const off = rest.match(/^(?:off|tirar|remover|cancelar)\s+(\S+)/i);
|
|
2789
|
+
if (off) {
|
|
2790
|
+
const r = A.remover(projectDir(), off[1]);
|
|
2791
|
+
console.log(r.ok ? c.ok(` Tirei: ${r.item.quando} · ${r.item.pedido.slice(0, 60)}`) : c.warn(` ${r.erro}`));
|
|
2792
|
+
break;
|
|
2793
|
+
}
|
|
2794
|
+
if (!rest) {
|
|
2795
|
+
const lista = A.listar(projectDir());
|
|
2796
|
+
if (!lista.length) { console.log(c.muted(' Nada agendado. Exemplo: /schedule "toda segunda às 9h" resuma o que mudou na semana')); break; }
|
|
2797
|
+
console.log(c.white(' Agendados neste projeto:'));
|
|
2798
|
+
lista.forEach((x, i) => console.log(` ${c.brand(String(i + 1))} ${c.white(x.quando)} ${c.muted(x.pedido.slice(0, 60))}`));
|
|
2799
|
+
console.log(c.muted(' O resultado de cada dia fica em .primocode/agendados/<data>.md · /schedule off <número> tira um.'));
|
|
2800
|
+
break;
|
|
2801
|
+
}
|
|
2802
|
+
const { quando, pedido } = A.separar(rest);
|
|
2803
|
+
const r = A.criar(projectDir(), quando, pedido);
|
|
2804
|
+
if (!r.ok) { console.log(c.warn(` ${r.erro}`)); break; }
|
|
2805
|
+
console.log(c.ok(` Agendado: ${r.item.quando}. O resultado vai para .primocode/agendados/<data>.md`));
|
|
2806
|
+
console.log(c.muted(r.relogio ? ' Roda sozinho, mesmo com o PrimoCode fechado (o Mac precisa estar ligado). /schedule off ' + r.item.id + ' tira.'
|
|
2807
|
+
: ' Atenção: o relógio automático só existe no Mac. O pedido ficou salvo, mas não vai rodar sozinho neste computador.'));
|
|
2808
|
+
break;
|
|
2809
|
+
}
|
|
2810
|
+
/* /ship: site estático, Next e app Node simples vão pro ar de verdade (lib/publicar.js); o resto cai no guia
|
|
2811
|
+
de fábrica (comandos/ship.md), que também vale pro /ship.md que a pessoa escreveu. */
|
|
2812
|
+
case 'ship': {
|
|
2813
|
+
const guia = comandosDaPessoa().find((x) => x.nome === 'ship');
|
|
2814
|
+
if (guia && guia.origem !== 'primocode') { console.log(c.dim(` ⎿ /ship · ${guia.origem}`)); await sendPrompt(comandosLib.expandir(guia, rest)); break; }
|
|
2815
|
+
const r = await require('../publicar.js').publicar(projectDir(), { log: (l) => console.log(c.muted(' ' + l)), confirmar: (q) => confirm(q) });
|
|
2816
|
+
if (r.guiado) {
|
|
2817
|
+
if (!guia) { console.log(c.err(' Não achei o guia de fábrica (comandos/ship.md).')); break; }
|
|
2818
|
+
console.log(c.muted(' Este projeto eu não publico sozinho: vou te guiar passo a passo.'));
|
|
2819
|
+
await sendPrompt(comandosLib.expandir(guia, rest));
|
|
2820
|
+
break;
|
|
2821
|
+
}
|
|
2822
|
+
if (r.recusou) console.log(c.muted(' Tudo bem, não enviei nada.'));
|
|
2823
|
+
else console.log(r.ok ? c.ok(` Seu projeto está no ar: ${r.url}`) : c.warn(` ${r.erro}`));
|
|
2824
|
+
break;
|
|
2825
|
+
}
|
|
2826
|
+
case 'timeline': {
|
|
2827
|
+
const arquivo = require('../session/linha-do-tempo').gravar(projectDir());
|
|
2828
|
+
const r = await tools.openInBrowser(arquivo);
|
|
2829
|
+
if (r && r.ok === false) console.log(c.muted(' A página está em: ') + arquivo);
|
|
2830
|
+
else console.log(c.ok(' Abri a história do projeto no navegador.') + c.dim(' ' + shortPath(arquivo)));
|
|
2831
|
+
break;
|
|
2832
|
+
}
|
|
2833
|
+
|
|
2834
|
+
|
|
2835
|
+
case 'read': {
|
|
2836
|
+
if (!rest) { console.log(c.err('Uso: /read <arquivo>')); break; }
|
|
2837
|
+
try {
|
|
2838
|
+
const content = fs.readFileSync(path.resolve(projectDir(), rest), 'utf-8');
|
|
2839
|
+
console.log(c.muted(`\n--- ${rest} ---\n`));
|
|
2840
|
+
console.log(content.length > 2000 ? content.slice(0, 2000) + '\n…' : content);
|
|
2841
|
+
} catch { console.log(c.err(`Não consegui ler: ${rest}`)); }
|
|
2842
|
+
break;
|
|
2843
|
+
}
|
|
2844
|
+
|
|
2845
|
+
case 'run': {
|
|
2846
|
+
if (!rest) { console.log(c.err('Uso: /run <comando>')); break; }
|
|
2847
|
+
console.log(c.muted(`$ ${rest}`));
|
|
2848
|
+
const result = await tools.runShell(rest, 60000, projectDir());
|
|
2849
|
+
if (result.stdout) console.log(result.stdout);
|
|
2850
|
+
if (result.stderr) console.log(c.err(result.stderr));
|
|
2851
|
+
if (result.code !== 0) console.log(c.err(`exit ${result.code}`));
|
|
2852
|
+
break;
|
|
2853
|
+
}
|
|
2854
|
+
|
|
2855
|
+
/* /novo: projeto novo por ORDEM da pessoa. Sem ele, "crie um site de
|
|
2856
|
+
receitas" pode cair dentro de "site-receitas-velho" porque o nome
|
|
2857
|
+
parece (findSimilarProject) — e quem quer começar do zero não tem
|
|
2858
|
+
como dizer isso. Aqui a pasta nasce antes, com nome que não colide,
|
|
2859
|
+
e o pedido roda preso nela. */
|
|
2860
|
+
case 'new': {
|
|
2861
|
+
// sem nada: as 3 perguntas de quem nunca programou (era o /new)
|
|
2862
|
+
if (!rest) { await comecarPerguntas(); break; }
|
|
2863
|
+
await criarProjetoNovo(rest);
|
|
2864
|
+
break;
|
|
2865
|
+
}
|
|
2866
|
+
|
|
2867
|
+
/* /open sem nada (e /open) acha sozinho o que abrir: o servidor do
|
|
2868
|
+
projeto de pé, ou a index.html. Antes pedia o caminho, e quem não
|
|
2869
|
+
sabe que a página se chama index.html ficava parado aqui. */
|
|
2870
|
+
case 'open': {
|
|
2871
|
+
if (!rest) {
|
|
2872
|
+
const pastaAtual = projectDir();
|
|
2873
|
+
if (path.resolve(pastaAtual) === path.resolve(cfg.ROOT_DIR)) {
|
|
2874
|
+
console.log(c.muted(' Nenhum projeto aberto.') + c.dim(' /projects para escolher um'));
|
|
2875
|
+
break;
|
|
2876
|
+
}
|
|
2877
|
+
const alvo = await extra.acharAlvoAbrir(pastaAtual);
|
|
2878
|
+
if (!alvo) {
|
|
2879
|
+
console.log(c.muted(` Não achei página nem servidor em ${shortPath(pastaAtual)}.`));
|
|
2880
|
+
console.log(c.dim(' Peça "roda o projeto" ao Primo, ou /open <arquivo>. O app devia estar rodando? /port diz por que não abre.'));
|
|
2881
|
+
break;
|
|
2882
|
+
}
|
|
2883
|
+
const r = await tools.openInBrowser(alvo.url || alvo.caminho);
|
|
2884
|
+
if (r && r.ok === false) { console.log(c.err(` Não consegui abrir: ${r.error}`)); break; }
|
|
2885
|
+
console.log(c.ok(` Aberto: ${alvo.url || shortPath(alvo.caminho)}`) + c.dim(` (${alvo.porque})`));
|
|
2886
|
+
break;
|
|
2887
|
+
}
|
|
2888
|
+
const target = /^https?:\/\//i.test(rest) ? rest : path.resolve(projectDir(), rest);
|
|
2889
|
+
await tools.openInBrowser(target);
|
|
2890
|
+
console.log(c.ok(`Aberto: ${rest}`));
|
|
2891
|
+
break;
|
|
2892
|
+
}
|
|
2893
|
+
|
|
2894
|
+
case 'name': {
|
|
2895
|
+
// /name voz <Nome>: o nome do assistente de voz (o mesmo do /voice nome)
|
|
2896
|
+
const nomeVoz = rest.match(/^(?:voz|voice|assistente)\s+(.{2,20})$/i);
|
|
2897
|
+
if (nomeVoz) {
|
|
2898
|
+
const salvo = vozModo.definirNome(nomeVoz[1]);
|
|
2899
|
+
console.log(salvo ? c.ok(` Fechado: o assistente agora se chama ${salvo}. Vale na próxima vez que ligar o /voice.`) : c.err(' Nome inválido (1 ou 2 palavras, até 20 letras).'));
|
|
2900
|
+
break;
|
|
2901
|
+
}
|
|
2902
|
+
if (!rest) { console.log(c.muted(` Nome atual: ${state.config.userName || '(nenhum)'}`)); break; }
|
|
2903
|
+
state.config.userName = rest;
|
|
2904
|
+
cfg.saveConfig({ userName: rest });
|
|
2905
|
+
console.log(c.ok(`Feito! Vou te chamar de ${rest}.`));
|
|
2906
|
+
break;
|
|
2907
|
+
}
|
|
2908
|
+
|
|
2909
|
+
/* A galeria: todos lado a lado, número e nome em cima. Escolhe por
|
|
2910
|
+
nome ou número — na hora, se há teclado; senão pelo /mascot <n>.
|
|
2911
|
+
Num pipe não pergunta: a "resposta" seria o próximo comando. */
|
|
2912
|
+
// O kit de marca (lib/plugin/marca-kit.js): /marca criar|listar|usar <nome> [aqui]|mostrar|apagar <nome>
|
|
2913
|
+
case 'brand': {
|
|
2914
|
+
const kit = require('../plugin/marca-kit.js');
|
|
2915
|
+
const perguntar = async (t, p) => (String(await ask(`${c.brand('?')} ${t}${p ? c.muted(` [${p}]`) : ''}: `)).trim() || p || '');
|
|
2916
|
+
await kit.main((rest || 'mostrar').split(/\s+/), { perguntar, dizer: (t) => console.log(c.muted(t)), pasta: state.workDir || process.cwd() });
|
|
2917
|
+
break;
|
|
2918
|
+
}
|
|
2919
|
+
|
|
2920
|
+
case 'mascot': {
|
|
2921
|
+
const reac = rest.match(/^(reac(?:oes|ões)?|rea[cç][aã]o|reactions?)\s*(on|off|liga[r]?|desliga[r]?|sim|n[aã]o)?$/i);
|
|
2922
|
+
if (reac) {
|
|
2923
|
+
const quer = reac[2] ? /^(on|liga|ligar|sim)$/i.test(reac[2]) : state.config.reacoes === false;
|
|
2924
|
+
state.config.reacoes = quer;
|
|
2925
|
+
cfg.saveConfig({ reacoes: quer });
|
|
2926
|
+
console.log(c.ok(` Reações do mascote: ${quer ? 'ligadas' : 'desligadas'}`)
|
|
2927
|
+
+ (quer ? ' ' + ui.reacao(state.config.mascot, 'feliz').trim() : ''));
|
|
2928
|
+
break;
|
|
2929
|
+
}
|
|
2930
|
+
let pedido = rest;
|
|
2931
|
+
if (!pedido) {
|
|
2932
|
+
console.log('');
|
|
2933
|
+
console.log(ui.galeriaMascotes(state.config.mascot || 'primo', process.stdout.columns || 80));
|
|
2934
|
+
if (!process.stdin.isTTY || state.semTerminal) {
|
|
2935
|
+
console.log(c.muted(' Escolha: /mascot <nome ou número>') + c.dim(' · /mascot reacoes off desliga o rostinho'));
|
|
2936
|
+
break;
|
|
2937
|
+
}
|
|
2938
|
+
pedido = String(await ask(` ${c.brand('?')} Nome ou número ${c.dim('(Enter mantém)')}: `)).trim();
|
|
2939
|
+
if (!pedido) { console.log(c.muted(' Nada mudou.')); break; }
|
|
2940
|
+
}
|
|
2941
|
+
const m = ui.resolverMascote(pedido);
|
|
2942
|
+
if (!m) { console.log(c.err(` Não conheço "${pedido}".`) + c.dim(` São: ${ui.MASCOTES.join(', ')}`)); break; }
|
|
2943
|
+
state.config.mascot = m;
|
|
2944
|
+
cfg.saveConfig({ mascot: m });
|
|
2945
|
+
const info = ui.mascoteInfo(m);
|
|
2946
|
+
console.log('');
|
|
2947
|
+
const arte = ui.mascot(m);
|
|
2948
|
+
arte.forEach((l, i) => console.log(' ' + l + (i === 0 ? ' ' + c.bold(c.white(info.nome))
|
|
2949
|
+
: i === 1 ? ' ' + c.dim(`"${info.frase}"`) : '')));
|
|
2950
|
+
console.log(c.ok(`\n Mascote: ${m}`));
|
|
2951
|
+
break;
|
|
2952
|
+
}
|
|
2953
|
+
|
|
2954
|
+
case 'config': {
|
|
2955
|
+
console.log('');
|
|
2956
|
+
console.log(` ${c.muted('nome')} ${c.white(state.config.userName || '(nenhum)')}`);
|
|
2957
|
+
console.log(` ${c.muted('mascote')} ${c.white(state.config.mascot || 'primo')}${c.dim(state.config.reacoes === false ? ' · sem reações' : ' · com reações')}`);
|
|
2958
|
+
console.log(` ${c.muted('esforço')} ${c.white(state.config.effort)}${c.dim(' · /effort muda')}`);
|
|
2959
|
+
console.log(` ${c.muted('modelo')} ${c.white(state.config.model)}${c.dim(' (vem do esforço)')}`);
|
|
2960
|
+
console.log(` ${c.muted('modo')} ${c.white(state.mode)}`);
|
|
2961
|
+
console.log(` ${c.muted('servidor')} ${c.dim(state.config.server)}`);
|
|
2962
|
+
console.log(c.muted(`\n ${cfg.CONFIG_FILE}`));
|
|
2963
|
+
break;
|
|
2964
|
+
}
|
|
2965
|
+
|
|
2966
|
+
// Limpar aqui não apaga o que já subiu: encerra ESTA conversa e a
|
|
2967
|
+
// próxima pergunta abre outra. Apagar do histórico é decisão da
|
|
2968
|
+
// pessoa, e ela toma no app — não de raspão num comando de limpar tela.
|
|
2969
|
+
/* Resume a conversa por ordem da pessoa. Diferente do /clear: aqui
|
|
2970
|
+
nada é esquecido — o que já passou vira resumo e o fim continua
|
|
2971
|
+
cru, então dá para seguir de onde parou. */
|
|
2972
|
+
case 'compact': {
|
|
2973
|
+
if (!state.history.length) {
|
|
2974
|
+
console.log(c.muted(' A conversa está vazia — não há o que resumir.'));
|
|
2975
|
+
break;
|
|
2976
|
+
}
|
|
2977
|
+
const antes = memoria.usoDoContexto(state.memoria, state.history);
|
|
2978
|
+
await comprimirConversa(true);
|
|
2979
|
+
const depois = memoria.usoDoContexto(state.memoria, state.history);
|
|
2980
|
+
if (depois.tokens >= antes.tokens) {
|
|
2981
|
+
// Pode não haver o que dobrar (conversa curta, ou o servidor
|
|
2982
|
+
// recusou). Dizer isso é melhor que fingir que encolheu.
|
|
2983
|
+
console.log(c.muted(' Não deu para encolher mais desta vez.'));
|
|
2984
|
+
} else {
|
|
2985
|
+
console.log(c.ok(' Conversa resumida.')
|
|
2986
|
+
+ c.muted(` ctx ${antes.pct}% → ${depois.pct}%`));
|
|
2987
|
+
}
|
|
2988
|
+
refreshPrompt();
|
|
2989
|
+
break;
|
|
2990
|
+
}
|
|
2991
|
+
|
|
2992
|
+
case 'clear': state.history = []; state.memoria = memoria.nova();
|
|
2993
|
+
state.gravador.zerar(); console.log(c.ok('Conversa limpa.')); break;
|
|
2994
|
+
case 'cls': process.stdout.write('\x1Bc'); break;
|
|
2995
|
+
|
|
2996
|
+
/* O /status olha só o servidor. O /doctor olha tudo o que costuma
|
|
2997
|
+
ser o motivo de "não funciona" — e cada ✗ diz como consertar. */
|
|
2998
|
+
case 'doctor': {
|
|
2999
|
+
if (/^status$/i.test(rest)) { await mostrarStatus(); break; }
|
|
3000
|
+
const sp = new Spinner('conferindo').start();
|
|
3001
|
+
const linhas = await extra.diagnosticar({
|
|
3002
|
+
saude: () => api.getHealth(state.config.server, state.config.token),
|
|
3003
|
+
provedor: () => provedorLocal.atual(),
|
|
3004
|
+
conferirChave: (id, chave) => provedorLocal.conferir(id, chave),
|
|
3005
|
+
cliInstalado: (id) => require('../provider/local/motor-cli').instalado(id),
|
|
3006
|
+
acharChrome: () => require('../browser').findChrome(),
|
|
3007
|
+
raiz: cfg.ROOT_DIR,
|
|
3008
|
+
arquivoConfig: cfg.CONFIG_FILE,
|
|
3009
|
+
});
|
|
3010
|
+
sp.stop();
|
|
3011
|
+
console.log('');
|
|
3012
|
+
for (const l of linhas) {
|
|
3013
|
+
const marca = l.ok === true ? c.ok('✓') : l.ok === false ? c.err('✗') : c.dim('·');
|
|
3014
|
+
console.log(` ${marca} ${ui.padRight(c.white(l.item), 18)}${ui.truncate(c.muted(l.detalhe || ''), Math.max(20, (process.stdout.columns || 80) - 23))}`);
|
|
3015
|
+
if (l.conserto) console.log(` ${c.dim('→ ' + l.conserto)}`);
|
|
3016
|
+
}
|
|
3017
|
+
for (const l of require('../preparar.js').estudioLinhas()) linhas.push(l), console.log(` ${l.ok === true ? c.ok('✓') : l.ok === false ? c.err('✗') : c.dim('·')} ${ui.padRight(c.white(l.item), 18)}${c.muted(l.detalhe || '')}`), l.conserto && console.log(` ${c.dim('→ ' + l.conserto)}`);
|
|
3018
|
+
const ruins = linhas.filter((l) => l.ok === false).length;
|
|
3019
|
+
console.log(ruins ? c.warn(`\n ${ruins} ${ruins === 1 ? 'coisa para arrumar' : 'coisas para arrumar'}.`) : c.ok('\n Tudo certo.'));
|
|
3020
|
+
break;
|
|
3021
|
+
}
|
|
3022
|
+
|
|
3023
|
+
case 'usage': {
|
|
3024
|
+
const Lim = require('../config/limite.js');
|
|
3025
|
+
const querLimite = /^(limite|limit)\b/i.exec(rest) && rest.replace(/^\S+\s*/, '').replace(/[.\s]/g, '').replace(/mil$/i, '000');
|
|
3026
|
+
if (querLimite) { // /usage limite 100000 ensina o limite do plano; sem número, mostra o uso de hoje
|
|
3027
|
+
console.log(Lim.definirLimite(querLimite) ? c.ok(` Anotei: ${Number(querLimite).toLocaleString('pt-BR')} tokens por dia. Agora os pedidos grandes dizem quantos % gastam.`) : c.warn(' Não entendi o número. Exemplo: /usage limite 100000'));
|
|
3028
|
+
break;
|
|
3029
|
+
}
|
|
3030
|
+
guardarUsoDeHoje();
|
|
3031
|
+
const { linhas, total } = extra.resumoCusto(contadorDaSessao);
|
|
3032
|
+
const hojeL = Lim.resumoDeHoje({ tokens: Lim.usoDeHoje().tokens, limite: Lim.limiteConhecido() });
|
|
3033
|
+
if (!linhas.length) { console.log(c.muted(' Nenhum pedido ao modelo nesta sessão ainda.')); hojeL.forEach((l) => console.log(c.muted(' ' + l))); break; }
|
|
3034
|
+
const simples = extra.resumoSimples({ linhas, total });
|
|
3035
|
+
console.log('\n ' + c.white('Nesta conversa: ') + simples.frase);
|
|
3036
|
+
console.log(' ' + c.ok(simples.quemPaga));
|
|
3037
|
+
console.log(c.dim('\n Em tokens (a unidade que o modelo conta):'));
|
|
3038
|
+
for (const l of linhas) {
|
|
3039
|
+
console.log(` ${c.white(ui.padRight(l.provedor, 22))}${c.muted(ui.padRight(l.pedidos + (l.pedidos === 1 ? ' pedido' : ' pedidos'), 12))}`
|
|
3040
|
+
+ `${c.dim('enviou ')}${c.white(extra.fmtNumero(l.enviados))}${c.dim(' · recebeu ')}${c.white(extra.fmtNumero(l.recebidos))}${c.dim(' tokens' + (l.exato ? '' : ' (estimado)'))}${l.emCache ? c.dim(' · ') + c.ok(extra.fmtNumero(l.emCache) + ' do cache') : ''}`);
|
|
3041
|
+
}
|
|
3042
|
+
if (linhas.length > 1) {
|
|
3043
|
+
console.log(` ${c.white(ui.padRight('Total', 22))}${c.muted(ui.padRight(total.pedidos + ' pedidos', 12))}`
|
|
3044
|
+
+ `${c.dim('enviou ')}${c.white(extra.fmtNumero(total.enviados))}${c.dim(' · recebeu ')}${c.white(extra.fmtNumero(total.recebidos))}`);
|
|
3045
|
+
}
|
|
3046
|
+
if (linhas.some((l) => !l.exato)) console.log(c.dim('\n Estimado = caracteres ÷ 4. Conta cada pedido inteiro, com a conversa que vai junto.'));
|
|
3047
|
+
console.log(''); hojeL.forEach((l) => console.log(c.white(' ' + l)));
|
|
3048
|
+
break;
|
|
3049
|
+
}
|
|
3050
|
+
|
|
3051
|
+
/* O que o agente deixou de pé com run_background (lib/fundo.js). */
|
|
3052
|
+
case 'tasks': {
|
|
3053
|
+
const fundo = require('../fundo.js');
|
|
3054
|
+
const [sub, alvo] = rest.split(/\s+/).filter(Boolean);
|
|
3055
|
+
if (/^(rodar|run)$/i.test(sub || '')) {
|
|
3056
|
+
// A pessoa também deixa coisa de pé, sem pedir ao agente (como o /run, mas sem travar).
|
|
3057
|
+
const cmd = rest.replace(/^\S+\s*/, '');
|
|
3058
|
+
if (!cmd) { console.log(c.warn(' Qual comando? /tasks rodar npm run dev')); break; }
|
|
3059
|
+
const r = fundo.iniciar(cmd, { projectDir: projectDir(), env: tools.ambienteLimpo(process.env, tools.permitidasNoShell()) });
|
|
3060
|
+
console.log(r.ok ? c.ok(` ${r.id} rodando em segundo plano.`) + c.muted(' /tasks mostra a saída e o endereço.') : c.warn(` ${r.error}`));
|
|
3061
|
+
break;
|
|
3062
|
+
}
|
|
3063
|
+
if (/^(abrir|open)$/i.test(sub || '')) {
|
|
3064
|
+
// Sem id: a primeira que anunciou endereço — quase sempre é a única.
|
|
3065
|
+
const t = fundo.listar().find((x) => x.url && x.rodando && (!alvo || x.id === alvo));
|
|
3066
|
+
if (!t) { console.log(c.warn(alvo ? ` ${alvo} não anunciou endereço (ou já parou).` : ' Nada rodando com endereço pra abrir.')); break; }
|
|
3067
|
+
const r = await tools.openInBrowser(t.url);
|
|
3068
|
+
console.log(r && r.ok === false ? c.warn(` Não abriu: ${r.error}. Abra você: ${t.url}`) : c.ok(` Abri ${t.url}`));
|
|
3069
|
+
break;
|
|
3070
|
+
}
|
|
3071
|
+
if (/^(parar|stop|kill)$/i.test(sub || '')) {
|
|
3072
|
+
if (!alvo) { console.log(c.warn(' Qual? /tasks parar <id>')); break; }
|
|
3073
|
+
const r = fundo.parar(alvo);
|
|
3074
|
+
console.log(r.ok ? c.ok(` Parei ${alvo}.`) : c.warn(` ${r.error}`));
|
|
3075
|
+
break;
|
|
3076
|
+
}
|
|
3077
|
+
const lista = fundo.listar();
|
|
3078
|
+
if (!lista.length) { console.log(c.muted(' Nada rodando em segundo plano.')); break; }
|
|
3079
|
+
console.log('');
|
|
3080
|
+
for (const t of lista) {
|
|
3081
|
+
const estado = t.rodando ? c.ok('rodando') : c.muted(`terminou${t.codigo === null ? '' : ' (código ' + t.codigo + ')'}`);
|
|
3082
|
+
const tempo = t.segundos >= 60 ? `${Math.floor(t.segundos / 60)}min${String(t.segundos % 60).padStart(2, '0')}s` : `${t.segundos}s`;
|
|
3083
|
+
console.log(` ${c.white(ui.padRight(t.id, 12))}${ui.padRight(estado, 28)}${c.dim(ui.padRight(tempo, 9))}${ui.truncate(c.muted(t.comando), Math.max(20, (process.stdout.columns || 80) - 52))}`);
|
|
3084
|
+
if (t.url && t.rodando) console.log(` ${' '.repeat(12)}${c.brand(t.url)}`);
|
|
3085
|
+
}
|
|
3086
|
+
break;
|
|
3087
|
+
}
|
|
3088
|
+
|
|
3089
|
+
case 'videos': {
|
|
3090
|
+
console.log(require('../plugin/estudio/exportar.js').main(rest.split(/\s+/).filter(Boolean)).texto);
|
|
3091
|
+
break;
|
|
3092
|
+
}
|
|
3093
|
+
|
|
3094
|
+
/* /exportar: a conversa vira um .md local, com chave e senha escondidas (lib/session/exportar-conversa.js). */
|
|
3095
|
+
case 'export': {
|
|
3096
|
+
const conversa = state.history.filter((m) => m.role === 'user' || m.role === 'assistant');
|
|
3097
|
+
if (!conversa.length) { console.log(c.muted(' Ainda não tem conversa pra exportar: faça um pedido primeiro.')); break; }
|
|
3098
|
+
const arq = require('../session/exportar-conversa.js').gravar(conversa, { projeto: path.basename(projectDir()) });
|
|
3099
|
+
console.log(c.ok(` Conversa salva (${conversa.length} mensagens): `) + shortPath(arq));
|
|
3100
|
+
console.log(c.muted(' Chave e senha saem trocadas por [chave escondida]. É um arquivo seu, sem link público.'));
|
|
3101
|
+
break;
|
|
3102
|
+
}
|
|
3103
|
+
case 'copy': {
|
|
3104
|
+
const r = extra.copiar(state.lastResponse);
|
|
3105
|
+
if (r.ok) console.log(c.ok(' Copiado.') + c.dim(` ${state.lastResponse.length} caracteres · é só colar`));
|
|
3106
|
+
else console.log(c.muted(` Não copiei: ${r.error}.`));
|
|
3107
|
+
break;
|
|
3108
|
+
}
|
|
3109
|
+
|
|
3110
|
+
case 'history': {
|
|
3111
|
+
const achados = extra.buscarHistorico(cfg.HISTORY_FILE, rest, 20);
|
|
3112
|
+
if (!achados.length) {
|
|
3113
|
+
console.log(c.muted(rest ? ` Nada com "${rest}" nos seus pedidos.` : ' Nenhum pedido guardado ainda.'));
|
|
3114
|
+
console.log(c.dim(' /chats mostra as conversas inteiras da sua conta.'));
|
|
3115
|
+
break;
|
|
3116
|
+
}
|
|
3117
|
+
console.log('');
|
|
3118
|
+
const largura = Math.max(30, (process.stdout.columns || 80) - 34);
|
|
3119
|
+
for (const e of achados) {
|
|
3120
|
+
const quando = new Date(e.ts).toLocaleString('pt-BR', { dateStyle: 'short', timeStyle: 'short' });
|
|
3121
|
+
console.log(` ${c.dim(quando)} ${c.muted(ui.padRight(ui.truncate(e.project || e.mode || '', 14), 14))} `
|
|
3122
|
+
+ ui.truncate(c.white(String(e.prompt).replace(/\s+/g, ' ')), largura));
|
|
3123
|
+
}
|
|
3124
|
+
console.log(c.dim(`\n ${achados.length === 20 ? 'Os 20 mais recentes' : achados.length + ' pedido(s)'}${rest ? ` com "${rest}"` : ''} · /history <termo> filtra · /chats abre conversas`));
|
|
3125
|
+
break;
|
|
3126
|
+
}
|
|
3127
|
+
|
|
3128
|
+
case 'keys': {
|
|
3129
|
+
console.log('');
|
|
3130
|
+
for (const [tecla, faz] of extra.ATALHOS) console.log(` ${c.brand(ui.padRight(tecla, 20))}${c.muted(faz)}`);
|
|
3131
|
+
break;
|
|
3132
|
+
}
|
|
3133
|
+
|
|
3134
|
+
|
|
3135
|
+
/* ── AS SKILLS ───────────────────────────────────────────────────
|
|
3136
|
+
* `/skills` lista, `/install-skill` traz de um arquivo, e
|
|
3137
|
+
* `/marketplace` é a tela onde se navega e liga.
|
|
3138
|
+
*
|
|
3139
|
+
* Nenhum dos três pede confirmação para ligar ou desligar: skill é
|
|
3140
|
+
* TEXTO, e o pior que um texto ruim faz é dar um conselho ruim ao
|
|
3141
|
+
* modelo — que o usuário vê acontecendo, ação por ação, na tela.
|
|
3142
|
+
*/
|
|
3143
|
+
case 'skills': {
|
|
3144
|
+
const sub = rest.match(/^(store|loja|add|instalar)\b\s*(.*)$/i);
|
|
3145
|
+
if (sub && /^(store|loja)$/i.test(sub[1])) { await abrirMarketplace(); break; }
|
|
3146
|
+
if (sub) {
|
|
3147
|
+
const alvo = sub[2].trim();
|
|
3148
|
+
if (!alvo) {
|
|
3149
|
+
console.log(c.muted(' Uso: ') + c.brand('/skills add <caminho do SKILL.md>'));
|
|
3150
|
+
console.log(c.dim(' Ou abra o ') + c.brand('/skills store') + c.dim(' e escolha "New Skill" para escrever uma.'));
|
|
3151
|
+
break;
|
|
3152
|
+
}
|
|
3153
|
+
const r = await instalarComPortao(alvo);
|
|
3154
|
+
if (!r.ok) { console.log(c.err(` ${r.error}`)); break; }
|
|
3155
|
+
console.log(c.ok(` Skill instalada: ${r.nome}`) + c.muted(` (${shortPath(r.caminho)})`));
|
|
3156
|
+
console.log(c.dim(' Já está ligada. /skills mostra todas.'));
|
|
3157
|
+
break;
|
|
3158
|
+
}
|
|
3159
|
+
const lista = skills.listar();
|
|
3160
|
+
if (!lista.length) { console.log(c.muted(' Nenhuma skill instalada.')); break; }
|
|
3161
|
+
const ligadas = lista.filter((s) => s.ligada);
|
|
3162
|
+
console.log('');
|
|
3163
|
+
console.log(c.bold(c.white(' Skills')) + c.dim(` ${ligadas.length} de ${lista.length} ligadas`));
|
|
3164
|
+
console.log('');
|
|
3165
|
+
for (const s of lista) {
|
|
3166
|
+
const marca = s.ligada ? c.ok('●') : c.dim('○');
|
|
3167
|
+
console.log(` ${marca} ${c.white(ui.padRight(s.titulo, 28))}`
|
|
3168
|
+
+ c.dim(ui.truncate(s.descricao, (process.stdout.columns || 80) - 36)));
|
|
3169
|
+
}
|
|
3170
|
+
console.log('');
|
|
3171
|
+
console.log(c.dim(' /skills store liga e desliga · o corpo da skill só entra no pedido'));
|
|
3172
|
+
console.log(c.dim(' quando o assunto bate, para não gastar o teto de tokens à toa.'));
|
|
3173
|
+
break;
|
|
3174
|
+
}
|
|
3175
|
+
|
|
3176
|
+
|
|
3177
|
+
/* ── /voice ──────────────────────────────────────────────────────
|
|
3178
|
+
* O ouvido e a boca são Python (voz/primo_voz); o cérebro é este
|
|
3179
|
+
* terminal. Ver entradaDeVoz no main() e lib/plugin/voz.js.
|
|
3180
|
+
*/
|
|
3181
|
+
case 'voice': {
|
|
3182
|
+
/* ── O MODO VOZ É UMA FORMA DE DIGITAR ─────────────────────────
|
|
3183
|
+
Você fala; o que foi dito entra aqui como se tivesse sido
|
|
3184
|
+
digitado — a mesma fila, o mesmo recado no meio da tarefa, o
|
|
3185
|
+
mesmo roteador de conversa — e a resposta final sai em voz alta.
|
|
3186
|
+
O terminal continua seu: dá para falar e digitar ao mesmo tempo.
|
|
3187
|
+
|
|
3188
|
+
Desligar é o primeiro caso de propósito: quem quer fechar o
|
|
3189
|
+
microfone quer AGORA, sem esbarrar em checagem de dependência. */
|
|
3190
|
+
const argVoz = (rest || '').trim();
|
|
3191
|
+
// Só o painel (HUD em tela cheia no Mac; quadro no terminal fora dele).
|
|
3192
|
+
if (/^painel$/i.test(argVoz)) {
|
|
3193
|
+
const py = vozModo.python();
|
|
3194
|
+
if (!py) { console.log(c.err(' O painel precisa do Python 3.')); break; }
|
|
3195
|
+
if (vozPainel) { try { vozPainel.processo.kill(); } catch {} vozPainel = null; }
|
|
3196
|
+
vozPainel = vozModo.abrirPainel({ python: py });
|
|
3197
|
+
console.log(c.muted(vozPainel.tela ? ' Tela do Primo aberta — ESC esconde.' : ' Sem o painel gráfico aqui: rode `primocode voz painel` num terminal separado.'));
|
|
3198
|
+
break;
|
|
3199
|
+
}
|
|
3200
|
+
// /voice nome <Nome>: a pessoa dá o nome ao assistente (o nome não ativa nada: o modo voz só abre no clique).
|
|
3201
|
+
const mNome = argVoz.match(/^nome\s+(.{2,20})$/i);
|
|
3202
|
+
if (mNome) {
|
|
3203
|
+
const salvo = vozModo.definirNome(mNome[1]);
|
|
3204
|
+
console.log(salvo ? c.ok(` Fechado: o assistente agora se chama ${salvo}. Vale na próxima vez que ligar o /voice.`) : c.err(' Nome inválido (1 ou 2 palavras, até 20 letras).'));
|
|
3205
|
+
break;
|
|
3206
|
+
}
|
|
3207
|
+
if (/^(parar|stop|off|sair)$/i.test(argVoz)) {
|
|
3208
|
+
if (vozPainel) { try { vozPainel.processo.kill(); } catch {} vozPainel = null; }
|
|
3209
|
+
if (!vozEmEspera) { console.log(c.muted(vozPainel === null ? ' Modo voz e painel fechados.' : ' O modo voz não está ligado.')); break; }
|
|
3210
|
+
try { vozEmEspera.processo.kill(); } catch {}
|
|
3211
|
+
vozEmEspera = null;
|
|
3212
|
+
console.log(c.muted(' Modo voz desligado. O microfone fechou.'));
|
|
3213
|
+
break;
|
|
3214
|
+
}
|
|
3215
|
+
if (vozEmEspera) {
|
|
3216
|
+
console.log(c.muted(' O modo voz já está ouvindo — é só falar.') + c.dim(' /voice parar desliga.'));
|
|
3217
|
+
break;
|
|
3218
|
+
}
|
|
3219
|
+
|
|
3220
|
+
// "Instale tudo que precisa, rode tudo que precisa." Da segunda vez
|
|
3221
|
+
// em diante tudo já está lá, e isto leva um segundo.
|
|
3222
|
+
const sp = new Spinner('preparando o modo voz').start();
|
|
3223
|
+
const prep = await vozModo.preparar((msg) => { sp.text = msg; });
|
|
3224
|
+
sp.stop();
|
|
3225
|
+
if (!prep.ok) {
|
|
3226
|
+
console.log(c.err(` ${prep.error}`));
|
|
3227
|
+
if (prep.comoResolver) console.log(c.muted(` ${prep.comoResolver}`));
|
|
3228
|
+
for (const a of prep.avisos) console.log(c.dim(` ${a}`));
|
|
3229
|
+
break;
|
|
3230
|
+
}
|
|
3231
|
+
for (const a of prep.avisos) console.log(c.dim(` ${a}`));
|
|
3232
|
+
if (process.platform === 'darwin') { try { vozModo.instalarApp({ python: prep.python }); } catch { /* o app é bônus */ } }
|
|
3233
|
+
|
|
3234
|
+
const sessao = vozModo.abrir({
|
|
3235
|
+
python: prep.python,
|
|
3236
|
+
servidor: state.config.server,
|
|
3237
|
+
token: state.config.token,
|
|
3238
|
+
voz: state.config.voz || 'antonio',
|
|
3239
|
+
aoPronto: () => {
|
|
3240
|
+
console.log(' ' + c.bold(c.brand('🎙 Modo voz ligado')) + c.muted(' — é só falar. A resposta sai em voz alta.'));
|
|
3241
|
+
console.log(' ' + c.dim('Falar por cima corta a voz · digitar continua valendo · /voice parar desliga'));
|
|
3242
|
+
},
|
|
3243
|
+
aoParar: () => { try { require('../session/runner/act.js').interromper(); } catch { /* nada rodando */ } },
|
|
3244
|
+
aoOuvir: (texto) => { if (entradaDeVoz) entradaDeVoz(texto); },
|
|
3245
|
+
mostrar: (texto) => console.log(' ' + c.dim(texto)),
|
|
3246
|
+
});
|
|
3247
|
+
vozEmEspera = sessao;
|
|
3248
|
+
require('../plugin/voz-ponte').escutar((nome, args) => sessao.ferramenta(nome, args));
|
|
3249
|
+
sessao.pronto.then((r) => {
|
|
3250
|
+
if (vozEmEspera === sessao) vozEmEspera = null;
|
|
3251
|
+
if (r && !r.ok) console.log(c.err(` o modo voz fechou: ${r.error}`));
|
|
3252
|
+
});
|
|
3253
|
+
break;
|
|
3254
|
+
}
|
|
3255
|
+
|
|
3256
|
+
|
|
3257
|
+
/* ── /connectors ─────────────────────────────────────────────────
|
|
3258
|
+
* Só mostra. Não há o que configurar — os conectores vivem no
|
|
3259
|
+
* servidor, com as chaves dele, e é assim de propósito: a promessa do
|
|
3260
|
+
* produto é que a API já vem pronta.
|
|
3261
|
+
*
|
|
3262
|
+
* Então por que existe? Porque "a IA está lenta hoje" e "ele errou o
|
|
3263
|
+
* código" têm causas diferentes e invisíveis: qual conector atendeu.
|
|
3264
|
+
* Sem esta tela, a única resposta possível é dar de ombros. Com ela,
|
|
3265
|
+
* dá para ver que o preferido está fora e outro assumiu — e essa é a
|
|
3266
|
+
* primeira pergunta de todo suporte.
|
|
3267
|
+
*/
|
|
3268
|
+
case 'connectors': {
|
|
3269
|
+
const sp = new Spinner('lendo os conectores').start();
|
|
3270
|
+
let dados = null;
|
|
3271
|
+
try {
|
|
3272
|
+
dados = await api.getConectores(state.config.server, state.config.token);
|
|
3273
|
+
} catch (e) { sp.stop(); console.log(c.err(` Não deu para ler: ${ui.friendlyError(e)}`)); break; }
|
|
3274
|
+
sp.stop();
|
|
3275
|
+
|
|
3276
|
+
const lista = (dados && dados.conectores) || [];
|
|
3277
|
+
if (!lista.length) { console.log(c.muted(' O servidor não listou conector nenhum.')); break; }
|
|
3278
|
+
|
|
3279
|
+
console.log('');
|
|
3280
|
+
console.log(c.bold(c.white(' Conectores')) + c.dim(' — quem atende os seus pedidos'));
|
|
3281
|
+
console.log('');
|
|
3282
|
+
for (const cx of lista) {
|
|
3283
|
+
const marca = cx.ligado ? c.ok('●') : c.dim('○');
|
|
3284
|
+
const selos = [
|
|
3285
|
+
cx.gratis ? c.dim('grátis') : c.warn('pago'),
|
|
3286
|
+
cx.faz && cx.faz.ferramentas ? c.dim('ferramentas') : c.dim('só conversa'),
|
|
3287
|
+
].join(c.dim(' · '));
|
|
3288
|
+
console.log(` ${marca} ${c.white(ui.padRight(cx.nome, 24))}${selos}`);
|
|
3289
|
+
console.log(` ${c.dim(ui.truncate(cx.porque || '', (process.stdout.columns || 80) - 6))}`);
|
|
3290
|
+
}
|
|
3291
|
+
const dePe = lista.filter((x) => x.ligado).length;
|
|
3292
|
+
console.log('');
|
|
3293
|
+
console.log(c.muted(` ${dePe} de ${lista.length} de pé.`)
|
|
3294
|
+
+ c.dim(' Quem está fora não some da fila: entra assim que o servidor tiver a chave.'));
|
|
3295
|
+
console.log(c.dim(' Não há nada para você configurar — a API vem com o PrimoCode.'));
|
|
3296
|
+
break;
|
|
3297
|
+
}
|
|
3298
|
+
|
|
3299
|
+
/* A janela (/rc, /ide, `primo --app`) saiu na 10.0: o PrimoCode é
|
|
3300
|
+
o terminal. O nome antigo ainda responde, uma linha, para o dedo
|
|
3301
|
+
viciado não achar que a atualização quebrou. */
|
|
3302
|
+
case 'rc':
|
|
3303
|
+
case 'ide':
|
|
3304
|
+
console.log(c.muted(' A janela saiu na 10.0 — o PrimoCode agora é só o terminal.'));
|
|
3305
|
+
break;
|
|
3306
|
+
|
|
3307
|
+
/* A conta do PrimoCode (lib/config/conta.js). Padrão: abre o navegador, onde
|
|
3308
|
+
se cria a conta, entra ou redefine a senha. `/login senha` é o
|
|
3309
|
+
caminho sem navegador (SSH, servidor). */
|
|
3310
|
+
case 'login': {
|
|
3311
|
+
const partes = String(rest || '').trim().split(/\s+/);
|
|
3312
|
+
const jaEsta = conta.atual();
|
|
3313
|
+
if (jaEsta && !partes.includes('trocar')) {
|
|
3314
|
+
console.log(c.muted(' Já conectado como ') + c.brand(jaEsta.email || (jaEsta.uid.slice(0, 12) + '…'))
|
|
3315
|
+
+ c.muted(` · plano ${jaEsta.plano}`));
|
|
3316
|
+
console.log(c.dim(' Para entrar com outra conta: ') + c.brand('/login trocar'));
|
|
3317
|
+
break;
|
|
3318
|
+
}
|
|
3319
|
+
if (jaEsta || conta.doConectaAntigo()) conta.sair();
|
|
3320
|
+
|
|
3321
|
+
let r;
|
|
3322
|
+
if (partes.includes('senha')) {
|
|
3323
|
+
const email = String(await ask(c.brand(' E-mail: ')) || '').trim();
|
|
3324
|
+
if (!email) { console.log(c.muted(' Login cancelado.')); break; }
|
|
3325
|
+
const senha = await askSecret(c.brand(' Senha: '));
|
|
3326
|
+
if (!senha) { console.log(c.muted(' Login cancelado.')); break; }
|
|
3327
|
+
const sp = new Spinner('entrando').start();
|
|
3328
|
+
r = await conta.entrar({ email, senha });
|
|
3329
|
+
sp.stop();
|
|
3330
|
+
} else {
|
|
3331
|
+
const sp = new Spinner('esperando você entrar no navegador').start();
|
|
3332
|
+
r = await conta.entrarPeloNavegador({
|
|
3333
|
+
aviso: (url) => {
|
|
3334
|
+
sp.stop();
|
|
3335
|
+
console.log(c.muted(' Abri o navegador para você criar a conta ou entrar.'));
|
|
3336
|
+
console.log(c.dim(' Não abriu? Copie: ') + c.brand(url));
|
|
3337
|
+
console.log(c.dim(' Sem navegador aqui? ') + c.brand('/login senha'));
|
|
3338
|
+
sp.start();
|
|
3339
|
+
},
|
|
3340
|
+
});
|
|
3341
|
+
sp.stop();
|
|
3342
|
+
}
|
|
3343
|
+
if (!r.ok) { console.log(c.err(` ${r.error}`)); break; }
|
|
3344
|
+
console.log(c.ok(' Conectado.')
|
|
3345
|
+
+ c.muted(r.pro ? ` Plano ${r.plano}.` : ' Sua conta ainda não tem plano: ') + (r.pro ? '' : c.brand('/account plans')));
|
|
3346
|
+
return r;
|
|
3347
|
+
}
|
|
3348
|
+
|
|
3349
|
+
/* O histórico da conta — o MESMO que o app desktop e o celular
|
|
3350
|
+
mostram. Sem número, lista; com número, abre e continua dali. */
|
|
3351
|
+
case 'chats': {
|
|
3352
|
+
if (!conta.atual()) {
|
|
3353
|
+
console.log(c.muted(' Não conectado. ') + c.brand('/login')
|
|
3354
|
+
+ c.muted(' para ver suas conversas aqui, no app e no celular.'));
|
|
3355
|
+
break;
|
|
3356
|
+
}
|
|
3357
|
+
const sp = new Spinner('lendo suas conversas').start();
|
|
3358
|
+
const l = await nuvem.listarConversas({ limite: 20 });
|
|
3359
|
+
sp.stop();
|
|
3360
|
+
if (!l.ok) { console.log(c.err(` ${l.error}`)); break; }
|
|
3361
|
+
if (!l.conversas.length) {
|
|
3362
|
+
console.log(c.muted(' Nenhuma conversa salva ainda. A próxima já fica.'));
|
|
3363
|
+
break;
|
|
3364
|
+
}
|
|
3365
|
+
if (!rest) {
|
|
3366
|
+
console.log(c.white('\n Suas conversas'));
|
|
3367
|
+
l.conversas.forEach((x, i) => {
|
|
3368
|
+
const quando = x.atualizada
|
|
3369
|
+
? new Date(x.atualizada).toLocaleDateString('pt-BR') : '—';
|
|
3370
|
+
console.log(' ' + c.dim(String(i + 1).padStart(2))
|
|
3371
|
+
+ ' ' + c.white(x.titulo.slice(0, 52).padEnd(52))
|
|
3372
|
+
+ c.dim(`${String(x.mensagens).padStart(3)} msg ${quando}`));
|
|
3373
|
+
});
|
|
3374
|
+
console.log(c.dim('\n /chats 1 abre a primeira e continua dela.'));
|
|
3375
|
+
break;
|
|
3376
|
+
}
|
|
3377
|
+
const n = Number(rest);
|
|
3378
|
+
const alvo = l.conversas[n - 1];
|
|
3379
|
+
if (!alvo) { console.log(c.err(` Não achei a conversa ${rest}.`)); break; }
|
|
3380
|
+
const conv = await abrirConversa(alvo);
|
|
3381
|
+
if (!conv.ok) { console.log(c.err(` ${conv.error}`)); break; }
|
|
3382
|
+
console.log(c.ok(` ${alvo.titulo}`)
|
|
3383
|
+
+ c.muted(` · ${conv.mensagens.length} mensagens carregadas`));
|
|
3384
|
+
console.log(c.dim(' Pode continuar daqui — o que você disser volta pro app e pro celular.'));
|
|
3385
|
+
break;
|
|
3386
|
+
}
|
|
3387
|
+
|
|
3388
|
+
case 'logout': {
|
|
3389
|
+
if (!conta.atual()) { console.log(c.muted(' Você não está conectado.')); break; }
|
|
3390
|
+
conta.sair();
|
|
3391
|
+
console.log(c.ok(' Desconectado deste computador.')
|
|
3392
|
+
+ c.dim(' A conta continua intacta; entre de novo com /login.'));
|
|
3393
|
+
break;
|
|
3394
|
+
}
|
|
3395
|
+
|
|
3396
|
+
case 'account': {
|
|
3397
|
+
if (/^(plans?|planos?)$/i.test(rest)) { await mostrarPlanos(); break; }
|
|
3398
|
+
const eu = conta.atual();
|
|
3399
|
+
if (!eu) {
|
|
3400
|
+
console.log(c.muted(' Não conectado. ') + c.brand('/login') + c.muted(' para entrar.'));
|
|
3401
|
+
break;
|
|
3402
|
+
}
|
|
3403
|
+
const sp = new Spinner('conferindo').start();
|
|
3404
|
+
// O plano guardado é a foto do último login: quem sabe é o documento da conta.
|
|
3405
|
+
const s = await conta.sessao();
|
|
3406
|
+
sp.stop();
|
|
3407
|
+
console.log(c.white(' Conta ') + c.muted(eu.email || eu.uid));
|
|
3408
|
+
if (s.ok) {
|
|
3409
|
+
const ate = s.planoAte ? c.dim(` até ${new Date(s.planoAte).toLocaleDateString('pt-BR')}`) : '';
|
|
3410
|
+
console.log(c.white(' Plano ') + (s.pro ? c.brand(s.plano) + ate : c.muted('sem plano ') + c.brand('/account plans')));
|
|
3411
|
+
} else if (s.offline) {
|
|
3412
|
+
console.log(c.white(' Plano ') + c.muted(eu.plano) + c.dim(' (sem rede — último conhecido)'));
|
|
3413
|
+
} else {
|
|
3414
|
+
console.log(c.err(` ${s.error}`));
|
|
3415
|
+
}
|
|
3416
|
+
console.log(c.dim(' Senha: ') + c.brand(`${conta.SITE}/entrar#esqueci`));
|
|
3417
|
+
break;
|
|
3418
|
+
}
|
|
3419
|
+
|
|
3420
|
+
|
|
3421
|
+
case 'uninstall': {
|
|
3422
|
+
if (await confirm('Remover o PrimoCode? Seus projetos em ~/primocode NÃO serão apagados.')) {
|
|
3423
|
+
await tools.uninstall();
|
|
3424
|
+
} else console.log(c.muted('Cancelado.'));
|
|
3425
|
+
break;
|
|
3426
|
+
}
|
|
3427
|
+
|
|
3428
|
+
case 'version': console.log(c.brand(`PrimoCode v${VERSION}`)); break;
|
|
3429
|
+
// rl.close() em vez de process.exit(): sair na marra descarta o que
|
|
3430
|
+
// ainda estava no buffer de saída.
|
|
3431
|
+
case 'exit': if (rl) rl.close(); break;
|
|
3432
|
+
/* ── OS COMANDOS APOSENTADOS ──────────────────────────────────────
|
|
3433
|
+
* `/claude`, `/gpt`, `/codex` e `/key` existiam quando o PrimoCode
|
|
3434
|
+
* rodava em cima da assinatura da própria pessoa: ela instalava o
|
|
3435
|
+
* Claude Code ou o Codex, colava uma chave de API, e só então o
|
|
3436
|
+
* agente pensava.
|
|
3437
|
+
*
|
|
3438
|
+
* Isso acabou. A API vem configurada no produto: quem entra na conta
|
|
3439
|
+
* já tem motor, e não há provedor nenhum para escolher.
|
|
3440
|
+
*
|
|
3441
|
+
* Eles não somem calados. Quem tem o dedo viciado em `/claude` e
|
|
3442
|
+
* bate num "comando não existe" conclui que a atualização quebrou
|
|
3443
|
+
* alguma coisa — e não vai procurar no /help, vai desinstalar. */
|
|
3444
|
+
case 'api': {
|
|
3445
|
+
await comandoApi(rest);
|
|
3446
|
+
break;
|
|
3447
|
+
}
|
|
3448
|
+
|
|
3449
|
+
/* O servidor aqui, no computador da pessoa, até a sessão acabar
|
|
3450
|
+
(lib/offline.js). "Enquanto não tenho acesso ao Railway, eu testo
|
|
3451
|
+
com o projeto rodando localmente." (24/09/2026) */
|
|
3452
|
+
case 'offline': {
|
|
3453
|
+
if (/^(off|sair|desligar|parar)$/i.test(rest)) {
|
|
3454
|
+
if (!state.servidorAntes) { console.log(c.muted(' O /offline não está ligado.')); break; }
|
|
3455
|
+
offline.desligar();
|
|
3456
|
+
state.config.server = state.servidorAntes;
|
|
3457
|
+
state.servidorAntes = null;
|
|
3458
|
+
console.log(c.ok(' Voltei ao servidor de antes: ') + c.dim(state.config.server));
|
|
3459
|
+
break;
|
|
3460
|
+
}
|
|
3461
|
+
if (state.servidorAntes) { console.log(c.muted(' Já está no servidor local: ') + c.dim(state.config.server) + c.muted(' · /offline off volta')); break; }
|
|
3462
|
+
const chaves = offline.prepararEnv();
|
|
3463
|
+
if (chaves.criado || !chaves.temChave) {
|
|
3464
|
+
console.log(c.warn(` ${chaves.criado ? 'Criei' : 'Falta chave em'} ${chaves.arquivo}`));
|
|
3465
|
+
console.log(c.muted(' Cole nele as chaves do Render (primocode-server → Environment), uma por linha:'));
|
|
3466
|
+
console.log(c.dim(' GROQ_API_KEY=… OPENROUTER_API_KEY=… GEMINI_API_KEY=…'));
|
|
3467
|
+
console.log(c.muted(' Depois rode ') + c.brand('/offline') + c.muted(' de novo.'));
|
|
3468
|
+
break;
|
|
3469
|
+
}
|
|
3470
|
+
const dir = offline.acharServidor({ pedido: rest });
|
|
3471
|
+
const sp = new Spinner('subindo o servidor aqui').start();
|
|
3472
|
+
const r = await offline.ligar({ dir, env: chaves.env });
|
|
3473
|
+
sp.stop();
|
|
3474
|
+
if (!r.ok) {
|
|
3475
|
+
console.log(c.err(' ' + r.error));
|
|
3476
|
+
if (r.comoResolver) console.log(c.dim(' → ' + r.comoResolver));
|
|
3477
|
+
break;
|
|
3478
|
+
}
|
|
3479
|
+
state.servidorAntes = state.config.server;
|
|
3480
|
+
state.config.server = r.url;
|
|
3481
|
+
console.log(c.ok(` Servidor ${r.versao || ''} ${r.reaproveitado ? 'que já estava de pé' : 'rodando aqui'}: `) + c.dim(r.url));
|
|
3482
|
+
console.log(c.dim(` ${dir || ''}${dir ? ' · ' : ''}chaves: ${chaves.nomes.join(', ')}${r.reaproveitado ? '' : ' · log em ' + offline.ARQUIVO_LOG}`));
|
|
3483
|
+
if (provedorLocal.atual()) console.log(c.warn(' Atenção: o /api está ligado e fala direto com a IA. Para usar o servidor local, /api off.'));
|
|
3484
|
+
console.log(c.muted(' Vale até fechar o PrimoCode. ') + c.brand('/offline off') + c.muted(' volta antes.'));
|
|
3485
|
+
break;
|
|
3486
|
+
}
|
|
3487
|
+
|
|
3488
|
+
/* Os comandos da pessoa: lista, e explica como fazer o dela. */
|
|
3489
|
+
case 'styles': {
|
|
3490
|
+
// Os kits de estilo de motion (lib/plugin/kits.js): a lista no terminal e a galeria (capa + preview + nome).
|
|
3491
|
+
const K = require('../plugin/kits.js');
|
|
3492
|
+
const a = String(rest || '').trim();
|
|
3493
|
+
if (a && !/^(galeria|abrir|lista)$/i.test(a)) {
|
|
3494
|
+
const k = K.achar(a);
|
|
3495
|
+
if (!k) { console.log(c.warn(` Não achei o estilo "${a}". /styles mostra todos.`)); break; }
|
|
3496
|
+
console.log(` ${c.brand(k.nome)} ${c.muted(`(${k.slug} · ${k.familia})`)}`);
|
|
3497
|
+
console.log(` ${k.descricao}`);
|
|
3498
|
+
if (k.quando.length) console.log(c.muted(` Serve pra: ${k.quando.slice(0, 3).join('; ')}`));
|
|
3499
|
+
if (!K.previewPronto(k)) console.log(c.muted(' Renderizando o preview aqui (uma vez só)…'));
|
|
3500
|
+
const r = await K.main(['preview', k.slug], { aoFalar: (t) => process.stdout.write(c.muted(`\r ⎿ ${t}`.padEnd(60))) });
|
|
3501
|
+
process.stdout.write('\n');
|
|
3502
|
+
if (r.ok && r.video) { if (process.env.PRIMOCODE_APP !== '1') tools.openInBrowser(r.video); console.log(c.ok(` ${r.texto}`)); }
|
|
3503
|
+
else console.log(c.warn(` ${r.texto}`));
|
|
3504
|
+
console.log(c.muted(` Pra usar: peça o vídeo dizendo "estilo ${k.nome.split(' · ')[0].toLowerCase()}".`));
|
|
3505
|
+
break;
|
|
3506
|
+
}
|
|
3507
|
+
for (const l of K.listaParaPessoa()) console.log(/^\s/.test(l) ? c.muted(l) : ` ${c.brand(l)}`);
|
|
3508
|
+
if (a.toLowerCase() === 'lista') break;
|
|
3509
|
+
// a tela de estilos (os kits no carrossel da tela de gosto): no terminal abre no navegador, no app numa janela
|
|
3510
|
+
console.log(c.muted(` Abri a tela de estilos${process.env.PRIMOCODE_APP === '1' ? '' : ' no navegador'} (até 10 min). Escolha um estilo ou feche pra voltar.`));
|
|
3511
|
+
const r = await K.main(['galeria']);
|
|
3512
|
+
console.log((r.ok ? c.ok : c.muted)(` ${r.texto} · /styles <estilo> mostra o preview no terminal`));
|
|
3513
|
+
break;
|
|
3514
|
+
}
|
|
3515
|
+
case 'team': {
|
|
3516
|
+
const team = require('../team.js');
|
|
3517
|
+
const achados = team.instalados();
|
|
3518
|
+
const o = team.entender(rest, achados);
|
|
3519
|
+
if (o.erro) { console.log(c.warn(` ${o.erro}`)); break; }
|
|
3520
|
+
if (o.acao === 'status') {
|
|
3521
|
+
const ligado = achados.some((x) => x.nome === state.config.team) ? state.config.team : null;
|
|
3522
|
+
team.status(achados, ligado).forEach((l, i) => console.log(i === 0 ? c.white(` ${l}`) : c.muted(` ${l}`)));
|
|
3523
|
+
break;
|
|
3524
|
+
}
|
|
3525
|
+
if (o.acao === 'desligar') {
|
|
3526
|
+
state.config.team = null;
|
|
3527
|
+
cfg.saveConfig({ team: null });
|
|
3528
|
+
console.log(c.ok(' O PrimoCode volta a trabalhar sozinho.'));
|
|
3529
|
+
break;
|
|
3530
|
+
}
|
|
3531
|
+
if (o.acao === 'ligar') {
|
|
3532
|
+
state.config.team = o.nome;
|
|
3533
|
+
cfg.saveConfig({ team: o.nome });
|
|
3534
|
+
console.log(c.ok(` ${team.PARCEIROS[o.nome].titulo} ligado: o PrimoCode faz e ele revisa, só lendo.`));
|
|
3535
|
+
console.log(c.dim(` /team ${o.nome} faz <pedido> deixa ele fazer · /team off desliga`));
|
|
3536
|
+
break;
|
|
3537
|
+
}
|
|
3538
|
+
await parceiroFaz(o.nome, o.pedido);
|
|
3539
|
+
break;
|
|
3540
|
+
}
|
|
3541
|
+
|
|
3542
|
+
case 'commands': {
|
|
3543
|
+
const novo = rest.match(/^(novo|new|criar)\s+(\S+)$/i);
|
|
3544
|
+
if (novo) {
|
|
3545
|
+
const r = comandosLib.criar(novo[2]);
|
|
3546
|
+
if (!r.ok) { console.log(c.err(` ${r.error}`)); break; }
|
|
3547
|
+
cacheComandos.em = 0;
|
|
3548
|
+
console.log(c.ok(` Criado: /${path.basename(r.arquivo, '.md')}`) + c.muted(' abra e escreva o pedido:'));
|
|
3549
|
+
console.log(' ' + c.white(r.arquivo));
|
|
3550
|
+
break;
|
|
3551
|
+
}
|
|
3552
|
+
const lista = comandosDaPessoa();
|
|
3553
|
+
console.log(c.white('\n Seus comandos'));
|
|
3554
|
+
for (const x of lista) {
|
|
3555
|
+
console.log(` ${c.brand(ui.padRight('/' + x.nome, 14))}${c.dim(ui.padRight(x.origem, 11))}${c.muted(x.descricao)}`);
|
|
3556
|
+
}
|
|
3557
|
+
console.log(c.dim('\n Um arquivo .md vira um comando: review.md é /review.'));
|
|
3558
|
+
console.log(c.dim(' ~/.primocode/comandos/ vale em todo projeto · <projeto>/.primocode/comandos/ só naquele.'));
|
|
3559
|
+
console.log(c.dim(' $ARGUMENTOS no texto recebe o que você digitar depois: /review o login.'));
|
|
3560
|
+
console.log(c.dim(' /commands novo <nome> cria um para você editar.'));
|
|
3561
|
+
break;
|
|
3562
|
+
}
|
|
3563
|
+
|
|
3564
|
+
case 'claude': case 'gpt': case 'codex': case 'key': {
|
|
3565
|
+
console.log(c.muted(' Não existe mais provedor para configurar.'));
|
|
3566
|
+
console.log(c.muted(' A API já vem com o PrimoCode: entrou na conta, pode usar.'));
|
|
3567
|
+
console.log(c.dim(' /effort escolhe o esforço · /account mostra o seu plano'));
|
|
3568
|
+
break;
|
|
3569
|
+
}
|
|
3570
|
+
|
|
3571
|
+
default: {
|
|
3572
|
+
// "/" sozinho abre o menu; um prefixo único autopreenche e executa
|
|
3573
|
+
// ("/eff" → /effort); prefixo ambíguo mostra as opções.
|
|
3574
|
+
if (!cmd) { mostrarMenuSlash(); break; }
|
|
3575
|
+
// Chegou aqui, não é embutido: o switch já atendeu todos eles.
|
|
3576
|
+
// Por isso um /help.md da pessoa nunca troca o /help de verdade.
|
|
3577
|
+
const proprio = comandosDaPessoa().find((x) => x.nome === nome);
|
|
3578
|
+
if (proprio) {
|
|
3579
|
+
console.log(c.dim(` ⎿ /${proprio.nome} · ${proprio.origem}`));
|
|
3580
|
+
// O MESMO caminho de um pedido digitado: modo, pasta, plano,
|
|
3581
|
+
// tudo. Um atalho que pulasse o sendPrompt pularia junto o
|
|
3582
|
+
// portão do plano e a escolha da pasta.
|
|
3583
|
+
await sendPrompt(comandosLib.expandir(proprio, rest));
|
|
3584
|
+
break;
|
|
3585
|
+
}
|
|
3586
|
+
let casam = comandosDoMenu().map(([nome]) => nome.slice(1)).filter((n) => n.startsWith(cmd.toLowerCase()));
|
|
3587
|
+
// Meio apelido antigo também serve: "/desf" chega no /undo.
|
|
3588
|
+
if (!casam.length) casam = nomes.porPrefixo(cmd).filter((n) => comandosDoMenu().some(([m]) => m === '/' + n));
|
|
3589
|
+
if (casam.length === 1) {
|
|
3590
|
+
console.log(c.dim(` → /${casam[0]}`));
|
|
3591
|
+
await handleSlash('/' + casam[0] + (rest ? ' ' + rest : ''));
|
|
3592
|
+
break;
|
|
3593
|
+
}
|
|
3594
|
+
if (casam.length > 1) {
|
|
3595
|
+
console.log(c.muted(` /${cmd}… pode ser:`));
|
|
3596
|
+
for (const n of casam) {
|
|
3597
|
+
const [, desc] = comandosDoMenu().find(([nome]) => nome === '/' + n);
|
|
3598
|
+
console.log(` ${c.brand(ui.padRight('/' + n, 12))}${c.dim(desc)}`);
|
|
3599
|
+
}
|
|
3600
|
+
break;
|
|
3601
|
+
}
|
|
3602
|
+
console.log(c.err(`Comando desconhecido: /${cmd}. Digite / para ver o menu.`));
|
|
3603
|
+
}
|
|
3604
|
+
}
|
|
3605
|
+
}
|
|
3606
|
+
|
|
3607
|
+
// ── Main ───────────────────────────────────────────────────────────────
|
|
3608
|
+
|
|
3609
|
+
function shortPath(p) {
|
|
3610
|
+
// Normaliza as barras antes de comparar — no Windows o cwd vem com "\"
|
|
3611
|
+
// e a home pode vir com "/", e aí o prefixo nunca batia.
|
|
3612
|
+
const norm = (s) => path.resolve(s).replace(/\\/g, '/');
|
|
3613
|
+
const home = norm(os.homedir());
|
|
3614
|
+
const full = norm(p);
|
|
3615
|
+
return full.startsWith(home + '/') ? '~' + full.slice(home.length) : full;
|
|
3616
|
+
}
|
|
3617
|
+
|
|
3618
|
+
/* O CLIENTE NOVO E O SERVIDOR VELHO.
|
|
3619
|
+
*
|
|
3620
|
+
* Quem declara ao modelo quais ferramentas existem é o servidor. Quando a
|
|
3621
|
+
* lista dele fica para trás, o que a pessoa vê é "a ferramenta não está
|
|
3622
|
+
* disponível" e tarefas que param no meio — duas frases que não apontam para
|
|
3623
|
+
* a causa. Uma linha no começo da sessão troca isso por algo acionável.
|
|
3624
|
+
*
|
|
3625
|
+
* Sem prender nada: a busca corre em paralelo e, se o servidor estiver
|
|
3626
|
+
* dormindo ou a rede fora, não se diz nada. Acusar o servidor porque a rede
|
|
3627
|
+
* caiu manda consertar o que não quebrou. */
|
|
3628
|
+
let jaConferiu = false;
|
|
3629
|
+
function conferirServidor() {
|
|
3630
|
+
if (jaConferiu) return;
|
|
3631
|
+
jaConferiu = true;
|
|
3632
|
+
const minimo = (pkg.primocode && pkg.primocode.servidorMinimo) || '';
|
|
3633
|
+
if (!minimo) return;
|
|
3634
|
+
// Com a chave própria (/api), quem pensa não é o servidor: a versão dele
|
|
3635
|
+
// não muda nada no que a pessoa pede.
|
|
3636
|
+
if (provedorLocal.atual()) return;
|
|
3637
|
+
const servidor = state.config.server;
|
|
3638
|
+
Promise.resolve()
|
|
3639
|
+
.then(() => api.getHealth(servidor, state.config.token))
|
|
3640
|
+
.then((saude) => {
|
|
3641
|
+
const r = compat.avaliar({ saude, minimo, servidor });
|
|
3642
|
+
const texto = compat.aviso(r, c);
|
|
3643
|
+
if (texto) console.log('\n' + texto + '\n');
|
|
3644
|
+
})
|
|
3645
|
+
.catch(() => {});
|
|
3646
|
+
}
|
|
3647
|
+
|
|
3648
|
+
async function main() {
|
|
3649
|
+
/* `primocode autoteste|preview|review|pesquisar`: entradas sem sessão (lib/cli/subcomandos.js). */
|
|
3650
|
+
if (require('./subcomandos.js').NOMES.includes(process.argv[2])) {
|
|
3651
|
+
process.exit(await require('./subcomandos.js').main(process.argv[2], process.argv.slice(3)));
|
|
3652
|
+
}
|
|
3653
|
+
/* `primocode --tentativas N "pedido"`: best of N em worktrees separados (lib/cli/tentativas.js). */
|
|
3654
|
+
if (process.argv.slice(2).some((a) => a === '--tentativas' || a.startsWith('--tentativas='))) {
|
|
3655
|
+
process.exit(await require('./tentativas.js').main(process.argv.slice(2)));
|
|
3656
|
+
}
|
|
3657
|
+
/* `primocode video <op>`: o editor de vídeo por linha do tempo
|
|
3658
|
+
(lib/plugin/video/). Sai ANTES de tudo — sem sessão, sem pasta padrão —
|
|
3659
|
+
porque quem chama é o agente pelo run_shell, na pasta da gravação. */
|
|
3660
|
+
if (process.argv[2] === 'video') {
|
|
3661
|
+
process.exit(await require('../plugin/video/cli.js').main(process.argv.slice(3)));
|
|
3662
|
+
}
|
|
3663
|
+
/* `primocode editor <acao> --json '{...}'`: a edição completa de vídeo falado
|
|
3664
|
+
(lib/plugin/editor-pro.js, motor do EDIT IA PRO), pelo run_shell quando o servidor
|
|
3665
|
+
ainda não declara a ferramenta editor_pro. Uma linha de JSON no stdout. */
|
|
3666
|
+
if (process.argv[2] === 'editor') {
|
|
3667
|
+
process.exit(await require('../plugin/editor-pro.js').main(process.argv.slice(3)));
|
|
3668
|
+
}
|
|
3669
|
+
/* `primocode gosto medir <video> [mais videos] [--salvar]`: os números do vídeo que a pessoa curtiu (lib/plugin/estudio/gosto-medir.js).
|
|
3670
|
+
Com --salvar, cada um entra no gosto como referência. (O /taste de dentro da sessão é outra entrada.) */
|
|
3671
|
+
// `primocode gosto` fora da sessão: o mesmo que o /gosto mostra (o que você escolheu, as referências, pra onde inclina)
|
|
3672
|
+
// `primocode porta`: o /porta fora da sessão, na pasta atual — é o que o agente roda pelo run_shell (lib/porta.js)
|
|
3673
|
+
if (process.argv[2] === 'porta') {
|
|
3674
|
+
const r = await require('../porta.js').diagnostico(path.resolve(process.argv[3] || process.cwd()));
|
|
3675
|
+
for (const l of r.linhas) console.log(' ' + l);
|
|
3676
|
+
process.exit(0);
|
|
3677
|
+
}
|
|
3678
|
+
if (process.argv[2] === 'gosto' && process.argv[3] === 'provar') {
|
|
3679
|
+
const G = require('../plugin/estudio/gosto.js'), P = require('../plugin/estudio/gosto-prova.js');
|
|
3680
|
+
const assunto = process.argv.slice(4).join(' ').trim() || 'um vídeo de apresentação';
|
|
3681
|
+
for (const l of P.texto(P.provar(G.pesos(G.ler()), { assunto }), assunto)) console.log(' ' + l);
|
|
3682
|
+
process.exit(0);
|
|
3683
|
+
}
|
|
3684
|
+
if (process.argv[2] === 'gosto' && (!process.argv[3] || process.argv[3] === 'ver')) {
|
|
3685
|
+
const G = require('../plugin/estudio/gosto.js');
|
|
3686
|
+
const linhas = G.listar(G.ler());
|
|
3687
|
+
if (!linhas.length) console.log(' Ainda não tem gosto salvo. Dentro do PrimoCode: /taste referencias recebe os vídeos que você curtiu.\n Daqui: primocode gosto medir <vídeo ou pasta> --salvar');
|
|
3688
|
+
else for (const l of linhas) console.log(' ' + l);
|
|
3689
|
+
process.exit(0);
|
|
3690
|
+
}
|
|
3691
|
+
if (process.argv[2] === 'gosto' && process.argv[3] === 'medir') {
|
|
3692
|
+
const salvar = process.argv.includes('--salvar'), json = process.argv.includes('--json');
|
|
3693
|
+
const { medir, explicar, videosDe } = require('../plugin/estudio/gosto-medir.js');
|
|
3694
|
+
const pedidos = process.argv.slice(4).filter((x) => x !== '--salvar' && x !== '--json');
|
|
3695
|
+
const arquivos = videosDe(pedidos.map((x) => path.resolve(x)));
|
|
3696
|
+
if (!pedidos.length) { console.error('Uso: primocode gosto medir <vídeo ou pasta> [mais] [--salvar] [--json]'); process.exit(1); }
|
|
3697
|
+
if (!arquivos.length) { console.error('Não achei vídeo (mp4, mov, m4v ou webm) nessa pasta.'); process.exit(1); }
|
|
3698
|
+
if (salvar && arquivos.length > 5) console.log(' O gosto guarda até 5 vídeos: ficam os 5 últimos desta lista.\n');
|
|
3699
|
+
const G = require('../plugin/estudio/gosto.js');
|
|
3700
|
+
let falhou = false;
|
|
3701
|
+
for (const f of arquivos) {
|
|
3702
|
+
const m = await medir(f);
|
|
3703
|
+
if (m.ok && salvar) G.adicionarReferencia(m, { nome: path.basename(f) });
|
|
3704
|
+
if (!m.ok) falhou = true;
|
|
3705
|
+
if (json) console.log(JSON.stringify(m, null, 2));
|
|
3706
|
+
else console.log(explicar(m, { cor: !!process.stdout.isTTY }).join('\n') + '\n');
|
|
3707
|
+
}
|
|
3708
|
+
if (!json) console.log(salvar ? ' Guardado no seu gosto. O próximo motion leva isso em conta (/taste mostra).' : ' Pra guardar como referência do seu gosto: --salvar');
|
|
3709
|
+
process.exit(falhou ? 1 : 0);
|
|
3710
|
+
}
|
|
3711
|
+
// `primocode motioncraft …`: o motion com o MotionCraft + a voz do PrimoCode.
|
|
3712
|
+
if (process.argv[2] === 'motioncraft') {
|
|
3713
|
+
process.exit(require('../plugin/motioncraft.js').main(process.argv.slice(3)));
|
|
3714
|
+
}
|
|
3715
|
+
// `primocode mcp …`: os servidores MCP pelo run_shell (lib/mcp/mcp.js).
|
|
3716
|
+
if (process.argv[2] === 'videos') {
|
|
3717
|
+
const r = require('../plugin/estudio/exportar.js').main(process.argv.slice(3));
|
|
3718
|
+
console.log(r.texto); process.exit(r.ok ? 0 : 1);
|
|
3719
|
+
}
|
|
3720
|
+
if (process.argv[2] === 'conversas' || process.argv[2] === 'conversa') {
|
|
3721
|
+
process.exit(await require('../app-chat.js').main(process.argv[2], process.argv.slice(3)));
|
|
3722
|
+
}
|
|
3723
|
+
if (process.argv[2] === 'menu-comandos') { // a paleta de / do app: os mesmos do terminal, mais os da pessoa
|
|
3724
|
+
const embutidos = new Set(SLASH_COMANDOS.map(([n]) => n));
|
|
3725
|
+
console.log(JSON.stringify({ ok: true, comandos: comandosDoMenu().map(([nome, descricao]) => ({ nome, descricao: ui.stripAnsi ? ui.stripAnsi(String(descricao)) : String(descricao), embutido: embutidos.has(nome) })) }));
|
|
3726
|
+
process.exit(0);
|
|
3727
|
+
}
|
|
3728
|
+
// `primocode kit …`: os kits de estilo de motion (lib/plugin/kits.js). Pelo run_shell do agente ele roda dentro do processo (lib/tool/tools.js).
|
|
3729
|
+
if (process.argv[2] === 'kit' || process.argv[2] === 'kits') {
|
|
3730
|
+
const r = await require('../plugin/kits.js').main(process.argv.slice(3), { projectDir: process.cwd(), aoFalar: (t) => process.stderr.write(` ⎿ ${t}\n`) });
|
|
3731
|
+
console.log(r.texto);
|
|
3732
|
+
process.exit(r.ok ? 0 : 1);
|
|
3733
|
+
}
|
|
3734
|
+
if (process.argv[2] === 'skill' || process.argv[2] === 'skills') {
|
|
3735
|
+
process.exit(require('../skill/skills.js').main(process.argv.slice(3)));
|
|
3736
|
+
}
|
|
3737
|
+
// `primocode planos`: a tabela comparativa, sem abrir a sessão.
|
|
3738
|
+
// `primocode voz nome <Nome>` / `primocode voz painel`: o Primo sem abrir a sessão.
|
|
3739
|
+
if (process.argv[2] === 'voz') {
|
|
3740
|
+
const vz = require('../plugin/voz.js');
|
|
3741
|
+
const [sub, ...resto] = process.argv.slice(3);
|
|
3742
|
+
if (sub === 'nome') {
|
|
3743
|
+
const n = vz.definirNome(resto.join(' '));
|
|
3744
|
+
console.log(n ? `Fechado: o assistente agora se chama ${n}.` : 'Uso: primocode voz nome <Nome> (1 ou 2 palavras)');
|
|
3745
|
+
process.exit(n ? 0 : 1);
|
|
3746
|
+
}
|
|
3747
|
+
if (sub === 'painel') {
|
|
3748
|
+
const py = vz.python();
|
|
3749
|
+
if (!py) { console.log('O painel precisa do Python 3.'); process.exit(1); }
|
|
3750
|
+
const r = vz.abrirPainel({ python: py });
|
|
3751
|
+
r.processo.on('close', () => process.exit(0));
|
|
3752
|
+
return;
|
|
3753
|
+
}
|
|
3754
|
+
if (sub === 'instalar-app') {
|
|
3755
|
+
const py = vz.python();
|
|
3756
|
+
if (!py) { console.log('O app precisa do Python 3 (rode /voice uma vez para preparar o ambiente).'); process.exit(1); }
|
|
3757
|
+
const r = vz.instalarApp({ python: py, dock: resto.includes('--dock') });
|
|
3758
|
+
console.log(r.ok ? `Primo.app instalado em ${r.app}. Abra pelo Launchpad, Spotlight ou Finder.` : `Não deu: ${r.erro || 'veja o log'}`);
|
|
3759
|
+
process.exit(r.ok ? 0 : 1);
|
|
3760
|
+
}
|
|
3761
|
+
console.log('Uso: primocode voz nome <Nome> | primocode voz painel | primocode voz instalar-app [--dock] (o resto é /voice dentro da sessão)');
|
|
3762
|
+
process.exit(0);
|
|
3763
|
+
}
|
|
3764
|
+
if (['doutor', 'doctor', 'preparar'].includes(process.argv[2])) {
|
|
3765
|
+
process.exit(await require('../preparar.js').main(process.argv.slice(2)));
|
|
3766
|
+
}
|
|
3767
|
+
if (process.argv[2] === 'planos') {
|
|
3768
|
+
const { loadConfig } = require('../config/config');
|
|
3769
|
+
const r = await planosTela.buscarPlanos(loadConfig().server);
|
|
3770
|
+
const eu = conta.atual();
|
|
3771
|
+
for (const l of planosTela.desenhar(r, { cores: c, atual: eu && eu.pro ? eu.plano : null, site: conta.SITE })) console.log(l);
|
|
3772
|
+
process.exit(0);
|
|
3773
|
+
}
|
|
3774
|
+
if (process.argv[2] === 'marca') {
|
|
3775
|
+
process.exit(await require('../plugin/marca-kit.js').main(process.argv.slice(3)));
|
|
3776
|
+
}
|
|
3777
|
+
if (process.argv[2] === 'mcp') {
|
|
3778
|
+
process.exit(await require('../mcp/mcp.js').main(process.argv.slice(3)));
|
|
3779
|
+
}
|
|
3780
|
+
cfg.ensureStructure();
|
|
3781
|
+
// O token da conta dura uma hora: renova agora e a cada minuto (lib/config/conta.js).
|
|
3782
|
+
await conta.manterVivo();
|
|
3783
|
+
|
|
3784
|
+
// Padrão fixo: ~/primocode, não importa de onde o comando foi dado. Antes ele
|
|
3785
|
+
// adotava a pasta atual do terminal, e o mesmo "crie um site" caía num lugar
|
|
3786
|
+
// diferente a cada vez — quem digitava não tinha como saber onde ia parar.
|
|
3787
|
+
state.workDir = cfg.ROOT_DIR;
|
|
3788
|
+
state.currentProject = null;
|
|
3789
|
+
state.workDirOrigem = 'padrao';
|
|
3790
|
+
// O projeto em que se estava na última sessão (até uma semana atrás): o
|
|
3791
|
+
// "continua o jogo" de amanhã cai nele, e não num projeto novo.
|
|
3792
|
+
// O app do Primo (voz) manda a pasta de cada pedido: PRIMOCODE_PASTA (+ ORIGEM) e nunca herda a última do terminal.
|
|
3793
|
+
const lembrado = process.env.PRIMOCODE_APP === '1'
|
|
3794
|
+
? (process.env.PRIMOCODE_PASTA && fs.existsSync(process.env.PRIMOCODE_PASTA)
|
|
3795
|
+
? { dir: process.env.PRIMOCODE_PASTA, origem: process.env.PRIMOCODE_PASTA_ORIGEM === '/dir' ? '/dir' : 'projeto' } : null)
|
|
3796
|
+
: cfg.projetoLembrado();
|
|
3797
|
+
if (lembrado && pastaSegura(lembrado.dir)) {
|
|
3798
|
+
state.workDir = lembrado.dir;
|
|
3799
|
+
state.currentProject = path.basename(lembrado.dir);
|
|
3800
|
+
state.workDirOrigem = lembrado.origem === '/dir' ? '/dir' : 'projeto';
|
|
3801
|
+
}
|
|
3802
|
+
|
|
3803
|
+
// Modo guardado entre sessões. O padrão é auto: sem ele, um "oi" gasta o
|
|
3804
|
+
// mesmo que uma refatoração.
|
|
3805
|
+
state.mode = ['primocode', 'chat', 'auto'].includes(process.env.PRIMOCODE_MODO || state.config.mode) ? (process.env.PRIMOCODE_MODO || state.config.mode) : 'auto';
|
|
3806
|
+
|
|
3807
|
+
// `-c` / `--continue` pode vir em qualquer posição e sai da lista: o
|
|
3808
|
+
// resto (one-shot, -f) segue sendo lido do jeito de sempre.
|
|
3809
|
+
const todos = process.argv.slice(2);
|
|
3810
|
+
const continuar = todos.some((a) => a === '-c' || a === '--continue');
|
|
3811
|
+
const fl = retomar.analisar(todos.filter((a) => a !== '-c' && a !== '--continue'));
|
|
3812
|
+
const args = fl.args;
|
|
3813
|
+
if (fl.erro) { console.error(fl.erro); process.exit(1); }
|
|
3814
|
+
if (fl.worktree) {
|
|
3815
|
+
// Antes de tudo: a sessão inteira nasce dentro do worktree.
|
|
3816
|
+
const w = retomar.criarWorktree(fl.worktree, process.cwd());
|
|
3817
|
+
if (!w.ok) { console.error(w.error); process.exit(1); }
|
|
3818
|
+
process.chdir(w.path);
|
|
3819
|
+
console.log(c.dim(` ⎿ worktree ${w.path} (branch ${w.branch})`));
|
|
3820
|
+
}
|
|
3821
|
+
|
|
3822
|
+
// Flags padrão de CLI — funcionam em qualquer máquina, úteis em scripts/CI.
|
|
3823
|
+
if (args[0] === '--version' || args[0] === '-v' || args[0] === '-V') {
|
|
3824
|
+
console.log(`PrimoCode v${VERSION}`);
|
|
3825
|
+
process.exit(0);
|
|
3826
|
+
}
|
|
3827
|
+
if (args[0] === '--help' || args[0] === '-h') {
|
|
3828
|
+
console.log(welcomeBox(VERSION, null, { mascot: state.config.mascot, userName: state.config.userName, modo: state.mode }));
|
|
3829
|
+
console.log(montarHelp());
|
|
3830
|
+
process.exit(0);
|
|
3831
|
+
}
|
|
3832
|
+
|
|
3833
|
+
/* `-p` / `--print`: o modo de script e CI (lib/cli/headless.js). Sem tela, o
|
|
3834
|
+
stdin entra no pedido, e --output-format json devolve um JSON só. */
|
|
3835
|
+
{
|
|
3836
|
+
const H = require('./headless.js');
|
|
3837
|
+
const h = H.analisar(args);
|
|
3838
|
+
if (h.ativo) {
|
|
3839
|
+
if (h.erro) { console.error(h.erro); process.exit(1); }
|
|
3840
|
+
if (h.permissao) {
|
|
3841
|
+
const perm = perigo.normalizarModo(h.permissao);
|
|
3842
|
+
state.config.permissoes = perm; // só nesta execução, não grava
|
|
3843
|
+
}
|
|
3844
|
+
const inicio = Date.now();
|
|
3845
|
+
const pedido = H.montarPedido(h.resto.filter((a) => a !== '-f'), await H.lerStdin());
|
|
3846
|
+
if (!pedido) { console.error('Uso: primocode -p "pedido" [--output-format json] [--permission-mode plan]'); process.exit(1); }
|
|
3847
|
+
if (typeof fl.resume === 'string') await retomarConversa(fl.resume);
|
|
3848
|
+
else if (continuar) await continuarUltima();
|
|
3849
|
+
// O script trabalha na pasta de onde rodou, não no último projeto (sem lembrar: é só nesta execução).
|
|
3850
|
+
const aqui = H.pastaDoScript({ cwd: process.cwd(), casa: os.homedir(), raiz: cfg.ROOT_DIR, app: process.env.PRIMOCODE_APP === '1' });
|
|
3851
|
+
if (aqui) { state.workDir = aqui; state.currentProject = path.basename(aqui); state.workDirOrigem = 'terminal'; }
|
|
3852
|
+
state.semTerminal = true;
|
|
3853
|
+
process.env.PRIMOCODE_SEM_TELA = '1'; // modo script: nenhuma tela de gosto abre no navegador (com PRIMOCODE_APP=1 o app abre pela linha `primocode:abrir-gosto`)
|
|
3854
|
+
if (process.env.PRIMOCODE_LOG_FERRAMENTAS === '1') { // o app do Primo registra cada ferramenta no log dele
|
|
3855
|
+
require('../plugin/voz-ponte').escutar((nome, a) => process.stderr.write(`ferramenta: ${nome} ${JSON.stringify(a || {}).slice(0, 220)}\n`));
|
|
3856
|
+
}
|
|
3857
|
+
let erro = null;
|
|
3858
|
+
const antes = state.history.length;
|
|
3859
|
+
const comando = isSlash(pedido); // `-p "/map tree"`: o comando roda como no terminal (o app usa isso)
|
|
3860
|
+
const texto = await H.capturar(async () => {
|
|
3861
|
+
try { if (comando) await handleSlash(pedido); else await sendPrompt(pedido); } catch (e) { erro = e.message || String(e); }
|
|
3862
|
+
}, { calar: h.formato === 'json' });
|
|
3863
|
+
await state.gravador.esperar(); // o último turno termina de subir, e o id da conversa existe
|
|
3864
|
+
if (h.formato === 'json') console.log(H.resultadoJson({ texto, erro, inicio, permissao: state.config.permissoes, conversa: state.gravador.id, markdown: H.ultimaResposta(state.history, antes) }));
|
|
3865
|
+
else if (erro) console.error(erro);
|
|
3866
|
+
process.exit(erro ? 1 : 0);
|
|
3867
|
+
}
|
|
3868
|
+
}
|
|
3869
|
+
|
|
3870
|
+
// Modo one-shot: primocode "crie um jogo de carro"
|
|
3871
|
+
if (args.length && !args[0].startsWith('-')) {
|
|
3872
|
+
const fileFlag = args.indexOf('-f');
|
|
3873
|
+
const words = fileFlag >= 0 ? args.slice(0, fileFlag) : args;
|
|
3874
|
+
const promptText = words.join(' ');
|
|
3875
|
+
|
|
3876
|
+
if (fileFlag >= 0 && args[fileFlag + 1]) {
|
|
3877
|
+
try {
|
|
3878
|
+
const fc = fs.readFileSync(path.resolve(args[fileFlag + 1]), 'utf-8');
|
|
3879
|
+
state.attachedFiles.push({ path: args[fileFlag + 1], content: fc });
|
|
3880
|
+
} catch { console.log(c.err(`Não consegui ler: ${args[fileFlag + 1]}`)); process.exit(1); }
|
|
3881
|
+
}
|
|
3882
|
+
|
|
3883
|
+
// Com -c, o pedido continua a última conversa em vez de chegar sozinho.
|
|
3884
|
+
if (typeof fl.resume === 'string') await retomarConversa(fl.resume);
|
|
3885
|
+
else if (continuar) await continuarUltima();
|
|
3886
|
+
/* O MESMO caminho do pedido digitado (sendPrompt). Este modo tinha um
|
|
3887
|
+
runAct próprio, e por isso ficava sem tudo o que vive lá: o plano em
|
|
3888
|
+
passos, a retomada automática, o @arquivo, o checkpoint do /desfazer. */
|
|
3889
|
+
state.semTerminal = true;
|
|
3890
|
+
global.__primocodeTarefa = promptText.slice(0, 60);
|
|
3891
|
+
await sendPrompt(promptText);
|
|
3892
|
+
global.__primocodeTarefa = null;
|
|
3893
|
+
process.exit(0);
|
|
3894
|
+
}
|
|
3895
|
+
|
|
3896
|
+
/* A TELA CHEIA do OpenCode (lib/tui/tela.js) é o padrão: a conversa rola em
|
|
3897
|
+
cima, a caixa fica presa no pé, a barra da direita mostra a sessão e o
|
|
3898
|
+
contexto, e sem conversa a home põe o logo e a caixa no meio da tela.
|
|
3899
|
+
PRIMOCODE_TELA=linha (ou "tela": "linha" no config) volta ao jeito
|
|
3900
|
+
antigo, que escreve em linha pelo terminal. */
|
|
3901
|
+
const telaCheia = process.stdout.isTTY && process.stdout.rows >= 16
|
|
3902
|
+
&& (process.env.PRIMOCODE_TELA || state.config.tela || 'cheia') !== 'linha';
|
|
3903
|
+
if (!telaCheia) {
|
|
3904
|
+
if (process.stdout.isTTY && process.stdout.rows >= 20) {
|
|
3905
|
+
const rows = process.stdout.rows;
|
|
3906
|
+
const alto = 8 + 6; // o logo com a versão + a caixa
|
|
3907
|
+
process.stdout.write('\n'.repeat(rows) + '\x1b[H' + '\n'.repeat(Math.max(0, Math.floor((rows - alto) / 2) - 1)));
|
|
3908
|
+
}
|
|
3909
|
+
console.log(welcomeBox(VERSION, state.workDir ? shortPath(state.workDir) : null, {
|
|
3910
|
+
pastaPadrao: state.workDirOrigem === 'padrao',
|
|
3911
|
+
}));
|
|
3912
|
+
}
|
|
3913
|
+
rl = entrada.criar({
|
|
3914
|
+
status: barraDeStatus,
|
|
3915
|
+
comandos: comandosDoMenu,
|
|
3916
|
+
vazio: ui.convite(),
|
|
3917
|
+
telaCheia,
|
|
3918
|
+
lateral: barraLateral,
|
|
3919
|
+
logoAnimado: (quadro, trabalhando) => ui.logoAnimado(state.config.mascot, quadro, trabalhando),
|
|
3920
|
+
agora: () => (ui.agora.texto && Date.now() - ui.agora.desde < 10 * 60 * 1000 ? ui.agora.texto : ''),
|
|
3921
|
+
versao: VERSION,
|
|
3922
|
+
logo: ui.logoComMascote(state.config.mascot),
|
|
3923
|
+
pasta: () => {
|
|
3924
|
+
const dir = state.workDir || process.cwd();
|
|
3925
|
+
const ramo = ramoDoGit(dir);
|
|
3926
|
+
return shortPath(dir) + (ramo ? ':' + ramo : '');
|
|
3927
|
+
},
|
|
3928
|
+
});
|
|
3929
|
+
if (telaCheia && state.workDirOrigem === 'padrao') {
|
|
3930
|
+
console.log(c.warn(` pasta padrão: ${shortPath(state.workDir)}`) + c.dim(' · /dir <pasta> para trabalhar numa sua'));
|
|
3931
|
+
}
|
|
3932
|
+
/* A última conversa desta pasta, em uma linha (lib/passagem.js). Uma vez por abertura, só aqui (o -p já saiu
|
|
3933
|
+
antes) e só se a pessoa não abriu já retomando (-c / --resume). */
|
|
3934
|
+
if (!state.dicaRetomarMostrada && !continuar && !fl.resume && state.workDirOrigem !== 'padrao') {
|
|
3935
|
+
state.dicaRetomarMostrada = true;
|
|
3936
|
+
try {
|
|
3937
|
+
const linha = require('../passagem.js').linhaDeAbertura(fs.readFileSync(path.join(state.workDir || process.cwd(), 'memory.md'), 'utf8').slice(-20000));
|
|
3938
|
+
if (linha) console.log(c.muted(' ' + linha));
|
|
3939
|
+
} catch { /* a dica nunca derruba a abertura */ }
|
|
3940
|
+
}
|
|
3941
|
+
// O spinner desenha dentro da caixa (lib/tui/entrada.js mostrarSpinner).
|
|
3942
|
+
if (rl.tty) Spinner.caixa = rl;
|
|
3943
|
+
ui.titulo('PrimoCode');
|
|
3944
|
+
|
|
3945
|
+
rl.prompt();
|
|
3946
|
+
|
|
3947
|
+
// Fila: o readline continua emitindo 'line' enquanto um pedido está sendo
|
|
3948
|
+
// processado. Sem enfileirar, dois pedidos rodariam sobrepostos.
|
|
3949
|
+
const queue = [];
|
|
3950
|
+
let busy = false;
|
|
3951
|
+
let closed = false;
|
|
3952
|
+
let saidBye = false;
|
|
3953
|
+
|
|
3954
|
+
/* ── Esc Esc: parar o agente no meio do trabalho ──
|
|
3955
|
+
* Um Esc avisa; o segundo (em até 2s) manda parar. A caixa não sabe o
|
|
3956
|
+
* que é "parar o agente" — ela só avisa que o Esc aconteceu, e quem
|
|
3957
|
+
* decide o que fazer é aqui.
|
|
3958
|
+
*
|
|
3959
|
+
* A sugestão fantasma, que morava aqui, foi junto com o readline: hoje
|
|
3960
|
+
* ela é desenhada pela própria caixa (ver lib/tui/entrada.js). */
|
|
3961
|
+
let ultimoEsc = 0;
|
|
3962
|
+
rl.on('escape', () => {
|
|
3963
|
+
if (!busy) { ultimoEsc = 0; return; }
|
|
3964
|
+
const agora = Date.now();
|
|
3965
|
+
if (agora - ultimoEsc < 2000) {
|
|
3966
|
+
ultimoEsc = 0;
|
|
3967
|
+
interromper();
|
|
3968
|
+
if (chatEmVoo) { try { chatEmVoo.abort(); } catch {} }
|
|
3969
|
+
console.log(c.warn(' ⏹ parando o agente…'));
|
|
3970
|
+
} else {
|
|
3971
|
+
ultimoEsc = agora;
|
|
3972
|
+
console.log(c.dim(' Esc de novo para parar o agente'));
|
|
3973
|
+
}
|
|
3974
|
+
});
|
|
3975
|
+
|
|
3976
|
+
// Ctrl+C com a caixa vazia: sair é sair, mas sem deixar o último turno
|
|
3977
|
+
// pela metade — o sayBye espera a gravação subir.
|
|
3978
|
+
rl.on('sigint', () => rl.close());
|
|
3979
|
+
rl.on('trocar-modo', trocarModo);
|
|
3980
|
+
|
|
3981
|
+
function sayBye() {
|
|
3982
|
+
if (saidBye) return;
|
|
3983
|
+
saidBye = true;
|
|
3984
|
+
|
|
3985
|
+
/* O MICROFONE FECHA JUNTO.
|
|
3986
|
+
O ouvinte de voz é um processo filho, e filho no POSIX não morre
|
|
3987
|
+
porque o pai saiu: ficaria um Python segurando o microfone depois
|
|
3988
|
+
de o terminal fechar — sem janela, sem jeito de desligar a não ser
|
|
3989
|
+
pelo gerenciador de tarefas, e com a luzinha da câmera do lado
|
|
3990
|
+
acesa. Matar aqui é o que faz "fechei o terminal" significar
|
|
3991
|
+
"fechei tudo". */
|
|
3992
|
+
if (vozEmEspera) {
|
|
3993
|
+
try { vozEmEspera.processo.kill(); } catch { /* já morreu */ }
|
|
3994
|
+
vozEmEspera = null;
|
|
3995
|
+
}
|
|
3996
|
+
// O último turno pode ainda estar subindo — gravar é de propósito
|
|
3997
|
+
// solto, para não segurar o prompt. Fechar o terminal em cima dele
|
|
3998
|
+
// perderia justamente a resposta que a pessoa acabou de ler, e ela
|
|
3999
|
+
// não veria falta nenhuma até procurar no celular.
|
|
4000
|
+
// O que ficou de pé em segundo plano morre junto: o filho com a saída
|
|
4001
|
+
// ligada ao PrimoCode seguraria o processo vivo depois do "Até logo!".
|
|
4002
|
+
require('../fundo.js').pararTodas();
|
|
4003
|
+
const fim = () => console.log(c.muted('\nAté logo!'));
|
|
4004
|
+
Promise.race([
|
|
4005
|
+
state.gravador.esperar(),
|
|
4006
|
+
// Rede pendurada não vira terminal pendurado. `unref` porque o
|
|
4007
|
+
// temporizador sozinho seguraria o processo por 3s mesmo quando a
|
|
4008
|
+
// gravação já terminou — um "Até logo!" seguido de três segundos
|
|
4009
|
+
// de nada é o tipo de coisa que quem usa chama de travado.
|
|
4010
|
+
new Promise((r) => { const t = setTimeout(r, 3000); if (t.unref) t.unref(); }),
|
|
4011
|
+
]).then(fim, fim);
|
|
4012
|
+
}
|
|
4013
|
+
|
|
4014
|
+
async function drain() {
|
|
4015
|
+
if (busy) return;
|
|
4016
|
+
busy = true;
|
|
4017
|
+
// A caixa esmaece enquanto ele trabalha, e a segunda linha da barra
|
|
4018
|
+
// troca os atalhos pelo que importa naquele momento: como parar.
|
|
4019
|
+
state.trabalhando = true;
|
|
4020
|
+
if (rl.trabalhando) rl.trabalhando(true);
|
|
4021
|
+
while (queue.length) {
|
|
4022
|
+
const text = queue.shift().trim();
|
|
4023
|
+
if (!text) continue;
|
|
4024
|
+
ui.titulo(`⠋ PrimoCode — ${text}`);
|
|
4025
|
+
// Comando (/effort, /help) não é trabalho do agente: a caixa e a
|
|
4026
|
+
// barra da direita só dizem "trabalhando" quando ele trabalha.
|
|
4027
|
+
if (rl.trabalhando) rl.trabalhando(!isSlash(text));
|
|
4028
|
+
try {
|
|
4029
|
+
if (ehBash(text)) await rodarBash(text);
|
|
4030
|
+
else if (isSlash(text)) await handleSlash(text);
|
|
4031
|
+
else {
|
|
4032
|
+
await sendPrompt(text, { digitado: true });
|
|
4033
|
+
}
|
|
4034
|
+
} catch (e) {
|
|
4035
|
+
fala.problema(e);
|
|
4036
|
+
if (vozEmEspera && vozEmEspera.estado) vozEmEspera.estado('erro');
|
|
4037
|
+
}
|
|
4038
|
+
// Pedido falado (ou tarefa que recebeu recado falado): a resposta
|
|
4039
|
+
// final sai em voz alta, resumida. O detalhe fica na tela.
|
|
4040
|
+
if (vozEmEspera && (deVoz.delete(text) || vozNaTarefa)) {
|
|
4041
|
+
vozNaTarefa = false;
|
|
4042
|
+
const ultima = state.history.slice().reverse().find((m) => m.role === 'assistant');
|
|
4043
|
+
if (ultima && ultima.content) vozEmEspera.falar(ultima.content);
|
|
4044
|
+
} else if (vozEmEspera && vozEmEspera.estado) vozEmEspera.estado('esperando');
|
|
4045
|
+
// Recado que chegou tarde demais para a tarefa (ela já tinha
|
|
4046
|
+
// acabado): vira o próximo pedido, na ordem. Nada se perde.
|
|
4047
|
+
queue.unshift(...sobrasDaCaixa());
|
|
4048
|
+
}
|
|
4049
|
+
busy = false;
|
|
4050
|
+
state.trabalhando = false;
|
|
4051
|
+
if (rl.trabalhando) rl.trabalhando(false);
|
|
4052
|
+
ui.titulo('PrimoCode');
|
|
4053
|
+
// Se o stdin já fechou (pipe, Ctrl+D), a despedida espera a fila terminar
|
|
4054
|
+
// — senão ela aparece antes do resultado do último pedido.
|
|
4055
|
+
if (closed) sayBye();
|
|
4056
|
+
else rl.prompt();
|
|
4057
|
+
}
|
|
4058
|
+
|
|
4059
|
+
rl.on('line', (line) => {
|
|
4060
|
+
if (pendingAsk) { const resolve = pendingAsk; pendingAsk = null; resolve(line); return; }
|
|
4061
|
+
// Abertura correndo: guarda em vez de mandar ao agente.
|
|
4062
|
+
if (segurando) { adiantadas.push(line); return; }
|
|
4063
|
+
/* Digitou com o agente no meio de uma tarefa: o recado entra NELA,
|
|
4064
|
+
depois do passo atual (ver a caixa em lib/session/runner/act.js), em vez de
|
|
4065
|
+
esperar a tarefa acabar para virar um pedido que não sabe de nada.
|
|
4066
|
+
Comando (/…) e shell (!…) continuam indo para a fila. */
|
|
4067
|
+
const t = line.trim();
|
|
4068
|
+
if (busy && t && !isSlash(t) && !ehBash(t) && mandarDuranteATarefa(t)) {
|
|
4069
|
+
console.log(c.dim(' ↳ recado guardado — entra na tarefa depois do passo atual'));
|
|
4070
|
+
return;
|
|
4071
|
+
}
|
|
4072
|
+
queue.push(line);
|
|
4073
|
+
drain();
|
|
4074
|
+
});
|
|
4075
|
+
|
|
4076
|
+
rl.on('close', () => { closed = true; if (!busy) sayBye(); });
|
|
4077
|
+
|
|
4078
|
+
/* A FALA ENTRA AQUI, pelo mesmo caminho da linha digitada: responde a
|
|
4079
|
+
pergunta pendente (a autorização, por exemplo — "pode" é resposta), vira
|
|
4080
|
+
recado se ele está no meio de uma tarefa, ou vira pedido na fila. O que
|
|
4081
|
+
veio falado é marcado para a resposta sair em voz alta. */
|
|
4082
|
+
const deVoz = new Set();
|
|
4083
|
+
let vozNaTarefa = false;
|
|
4084
|
+
entradaDeVoz = (texto) => {
|
|
4085
|
+
console.log(' ' + c.brand('🎙 ') + c.white(texto));
|
|
4086
|
+
if (pendingAsk) { const resolve = pendingAsk; pendingAsk = null; resolve(texto); return; }
|
|
4087
|
+
if (segurando) { adiantadas.push(texto); return; }
|
|
4088
|
+
if (busy && !isSlash(texto) && mandarDuranteATarefa(texto)) {
|
|
4089
|
+
vozNaTarefa = true;
|
|
4090
|
+
console.log(c.dim(' ↳ recado guardado — entra na tarefa depois do passo atual'));
|
|
4091
|
+
return;
|
|
4092
|
+
}
|
|
4093
|
+
deVoz.add(texto);
|
|
4094
|
+
queue.push(texto);
|
|
4095
|
+
drain();
|
|
4096
|
+
};
|
|
4097
|
+
|
|
4098
|
+
/* A ABERTURA — e ela roda AQUI, depois de `line` e `close` existirem.
|
|
4099
|
+
*
|
|
4100
|
+
* Estava antes deles. O `await` segurava o resto do main(), e tudo o que
|
|
4101
|
+
* chegasse pelo teclado nesse meio-tempo caía no vazio: não havia ouvinte
|
|
4102
|
+
* para pegar. Quem colasse dois comandos perdia o segundo, e quem
|
|
4103
|
+
* fechasse a entrada saía sem nem o "Até logo". Digitando devagar ninguém
|
|
4104
|
+
* via — os ouvintes ficam prontos milissegundos depois. */
|
|
4105
|
+
/* A FILA FICA SEGURA ENQUANTO A ABERTURA CORRE.
|
|
4106
|
+
*
|
|
4107
|
+
* `busy` já é o freio do `drain`, e é ele que se usa aqui. Sem isso, tudo
|
|
4108
|
+
* o que a pessoa digitar antes de a pergunta aparecer — e ela demora,
|
|
4109
|
+
* porque confere o plano no servidor — cai como PEDIDO no agente. Medido
|
|
4110
|
+
* no pacote publicado: o "2" da escolha da IA virou uma pergunta no chat,
|
|
4111
|
+
* e o modelo respondeu "Oi! Como posso ajudar?".
|
|
4112
|
+
*
|
|
4113
|
+
* O ouvinte de `line` continua atendendo o `ask` normalmente: ele olha o
|
|
4114
|
+
* `pendingAsk` antes da fila. O que fica retido é só o que não era
|
|
4115
|
+
* resposta a nada. */
|
|
4116
|
+
segurando = true;
|
|
4117
|
+
boasVindas.rodar({
|
|
4118
|
+
perguntar: ask,
|
|
4119
|
+
mostrar: (t) => console.log(t),
|
|
4120
|
+
cores: c,
|
|
4121
|
+
interativo: !!(process.stdin.isTTY && process.stdout.isTTY),
|
|
4122
|
+
conectado: () => conta.atual(),
|
|
4123
|
+
conectar: () => handleSlash('/login').then((r) => (r && r.ok === false ? r : conta.atual() || r)),
|
|
4124
|
+
sessao: () => conta.sessao(),
|
|
4125
|
+
}).then((r) => {
|
|
4126
|
+
// O bloqueio de quem não é Premium/Super. É de CORTESIA: este arquivo
|
|
4127
|
+
// vai publicado no npm com o código à vista. Quem segura de verdade é
|
|
4128
|
+
// o primocode-server, que tem a chave do provedor.
|
|
4129
|
+
state.liberado = !r || r.liberado !== false;
|
|
4130
|
+
state.motivoBloqueio = r && r.motivo;
|
|
4131
|
+
}).catch((e) => {
|
|
4132
|
+
// A abertura quebrou (rede, arquivo da conta). Não prende a pessoa, mas diz o que foi.
|
|
4133
|
+
state.liberado = true;
|
|
4134
|
+
console.log(c.muted(` (a abertura falhou: ${e && e.message ? e.message : e}. Se algo estranhar, rode /doctor)`));
|
|
4135
|
+
})
|
|
4136
|
+
// Depois da abertura, porque é nela que a pessoa entra na conta — e
|
|
4137
|
+
// sem conta não há conversa para achar.
|
|
4138
|
+
.then(() => (fl.resume === true ? escolherNaAbertura().catch(() => false)
|
|
4139
|
+
: fl.resume ? retomarConversa(fl.resume).catch(() => false)
|
|
4140
|
+
: continuar ? continuarUltima().catch(() => false) : null))
|
|
4141
|
+
.then(() => {
|
|
4142
|
+
// O que sobrou de adiantado não era resposta de nada: vira comando,
|
|
4143
|
+
// na ordem em que foi digitado. Nada se perde, só esperou a vez.
|
|
4144
|
+
segurando = false;
|
|
4145
|
+
while (adiantadas.length) queue.push(adiantadas.shift());
|
|
4146
|
+
if (queue.length) drain();
|
|
4147
|
+
else if (!closed) rl.prompt();
|
|
4148
|
+
conferirServidor();
|
|
4149
|
+
});
|
|
4150
|
+
}
|
|
4151
|
+
|
|
4152
|
+
main().catch((e) => { console.error(c.err(e.message || e)); process.exit(1); });
|