Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>RiseNew to Visual Studio Code? Get it now.
Rise

Rise

Eduardo de Freitas Arantes

| (0) | Free
Gerador de estrutura, highlight EJS, snippets, linter e testes Playwright para o padrão Rise v8 (Fastify + Node.js + MPA)
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Rise — Extensão VS Code

Versão VS Code Node.js Fastify EJS

Gerador de estrutura, highlight EJS, snippets, linter e testes Playwright para o padrão Rise v8 (Fastify)

Crie módulos completos com view isolada por módulo, promova components/partials para global
quando um segundo módulo precisar deles, e mantenha o isolamento garantido por lint — em segundos.


O que é o Rise

Rise é um padrão arquitetural para aplicações MPA (Multi-Page Application) construídas com Node.js + Fastify + EJS. A arquitetura organiza o projeto em camadas bem definidas (Shell, Page, Component, Partial) e estabelece convenções explícitas de nomenclatura, encapsulamento e separação de responsabilidades.

A extensão é o braço operacional da plataforma: ela transforma as convenções arquiteturais em código concreto, eliminando trabalho manual repetitivo e garantindo conformidade automática com o padrão.

┌──────────────────────────────────────────────────────────────────────────────┐
│                                RISE ECOSYSTEM                                │
├────────────┬─────────────────────┬──────────────────────────┬────────────────┤
│ SHELL      │ PAGE                │ COMPONENT                │ PARTIAL        │
├────────────┼─────────────────────┼──────────────────────────┼────────────────┤
│ index.ejs  │ modules/[mod]/view/ │ modules/[mod]/view/      │ view/partials/ │
│            │ pages/[pag]/        │ components/[cat]/[nome]/ │ _nome.ejs      │
│ Assets     │ ├ index.ejs         │ ├ index.ejs              │                │
│ globais    │ ├ style.css         │ ├ style.css              │ EJS puro       │
│ de public/ │ └ script.js         │ └ script.js              │ sem CSS/JS     │
│            │ (nunca é promovida) │                          │                │
└────────────┴─────────────────────┴──────────────────────────┴────────────────┘
   Component e Partial nascem sempre dentro do módulo — só saem de lá
   (para src/views/) quando um SEGUNDO módulo passa a precisar deles.

✨ O que a Extensão Faz

# Funcionalidade Benefício
1 Inicializar Projeto Estrutura completa + auth JWT + plugins Fastify em segundos
2 Novo Módulo Completo (Wizard) Plugin Factory + Controller + Service + Repository + Pages + sidebars opcionais + integração com menu lateral
3 Nova Page 3 arquivos com prefixo CSS e namespace JS derivados automaticamente
4 Novo Component Modal, sidebar ou component genérico com IIFE e window.Rise
5 Novo Partial Fragmento EJS puro em partials/
6 Rise Explorer Painel lateral com mapa visual do projeto
7 Validador em Tempo Real Diagnósticos automáticos de violações do padrão
8 Code Actions (💡) Correções automáticas com um clique
9 Highlight EJS Grammar próprio — tags <% %> coloridas sem sublinhado vermelho
10 EJS Formatter Shift+Alt+F formata .ejs preservando tags EJS intactas
11 Hover com Documentação Assinatura de components e APIs ao passar o mouse
12 Go to Definition Ctrl+Click em include() e window.Rise.*
13 Gerar Teste E2E Playwright gerado automaticamente a partir do template .ejs
14 31 Snippets EJS e JS para todos os padrões da arquitetura
15 Importar arquivo .spec Extrai estrutura de projeto a partir de um .spec do SpecForge
16 Gerar Teste Playwright Teste E2E gerado a partir do script.js do componente — métodos extraídos automaticamente
17 Linter CSS embutido Stylelint com regra rise/css-prefix — prefixo .rise- enforçado no painel Problems
18 Linter JS embutido ESLint com regras rise/namespace, rise/iife e rise/cross-module — namespace, IIFE e isolamento entre módulos validados ao salvar
19 Promover para Global 🌐 Move um component/partial local a um módulo para src/views/, reescrevendo automaticamente o include() de todo consumidor
20 Migrar projeto v7 → v8 rise-cli migrate move as pages de src/views/pages/[mod]/ para src/modules/[mod]/view/pages/, módulo a módulo, com --dry-run por padrão

📦 Instalação

Via VSIX (recomendado)

# 1. Clone ou baixe o repositório da extensão
# 2. Empacote (requer Node 20)
nvm use 20 && npm install -g @vscode/vsce
vsce package

# 3. Instale no VS Code
code --install-extension rise-1.0.0.vsix

Via Marketplace

Pesquise por "Rise" no painel de extensões do VS Code (Ctrl+Shift+X) ou acesse diretamente pelo Marketplace.

Requisitos

Componente Versão mínima
VS Code 1.85.0+
Node.js 18.0.0+
npm 9.0.0+

🚀 Primeiros Passos

1. Inicializar um projeto do zero

Ctrl+Shift+P → Rise: Inicializar Projeto → Confirmar
meu-projeto/
├── server.js                    ← Fastify configurado e pronto
├── package.json                 ← Dependências completas
├── .env                         ← SESSION_SECRET + JWT_SECRET + keys geradas
├── eslint.config.js             ← Regras rise/* embutidas
├── .stylelintrc.json            ← Regra rise/css-prefix embutida
├── tools/                       ← Plugins de lint vendorizados (sem dependência externa própria)
│   ├── eslint-plugin-rise/
│   └── stylelint-plugin-rise/
├── public/
│   ├── css/app.css
│   ├── js/app.js
│   └── vendor/
├── src/
│   ├── infrastructure/
│   │   ├── database/
│   │   │   ├── repository.js    ← Classe base Sequelize
│   │   │   ├── connection.js
│   │   │   ├── migrator.js      ← Umzug configurado
│   │   │   ├── models/
│   │   │   │   └── user.model.js
│   │   │   └── migrations/
│   │   │       └── 001-create-users.js
│   │   └── plugins/
│   │       ├── session.plugin.js
│   │       ├── flash.plugin.js
│   │       ├── locals.plugin.js  ← reply.render() / reply.renderPublic()
│   │       ├── static.plugin.js
│   │       ├── view.plugin.js    ← includer que resolve modules/ e views/ (Seção 4)
│   │       ├── jwt-auth.plugin.js
│   │       └── auth-guard.js    ← isAuthenticated + requireRole()
│   ├── modules/
│   │   └── auth/                ← Módulo completo de autenticação
│   │       ├── auth.plugin.js
│   │       ├── controllers/
│   │       ├── services/        ← bcrypt + JWT
│   │       ├── domain/
│   │       └── view/            ← ★ view local ao módulo (v8)
│   │           └── pages/login/ ← Page de login — nasce e permanece aqui, nunca é promovida
│   │               ├── index.ejs
│   │               ├── style.css
│   │               └── script.js
│   └── views/                   ← Só o que é GLOBAL (usado por mais de um módulo)
│       ├── index.ejs            ← Shell HTML
│       ├── pages/home/          ← Página inicial modelo
│       ├── components/
│       │   ├── menus/left/      ← sempre global
│       │   ├── modals/
│       │   └── sidebars/
│       └── partials/
│           ├── _page-header.ejs
│           ├── _empty-state.ejs
│           ├── _pagination.ejs
│           └── _alert-flash.ejs
└── tests/
    ├── unit/  ├── integration/  └── e2e/

Nenhum component/partial nasce em src/views/ — eles só chegam lá através do comando Promover para Global (ver seção "🔒 Isolamento entre Módulos" abaixo), na primeira vez que um segundo módulo precisa do mesmo artefato.

Credenciais do admin gerado: admin@rise.local / Admin@1234 Troque a senha antes do primeiro deploy em produção.

2. Instalar dependências e rodar

npm install
npx playwright install chromium  # instala o browser para testes E2E
npm run dev    # nodemon server.js → http://localhost:3000

3. Criar o primeiro módulo

Ctrl+Shift+P → Rise: Novo Módulo Completo ✨

Passo 1 — Nome do módulo:

operators

Passo 2 — Pages a criar (multi-select):

☑ list    ☑ detail    ☐ new    ☐ edit

Passo 3 — Components a criar (multi-select):

☑ sidebar-new    ☐ sidebar-edit

Passo 4 — Adicionar ao menu lateral:

☑ Sim → Label: Operators → Rota: /operators

Resultado gerado:

src/modules/operators/
├── operators.plugin.js           ← Two-Plugin Factory
├── controllers/
│   ├── operators.controller.js   ← GET /operators, /operators/:id → reply.render()
│   └── operators.api.controller.js ← GET /api/operators → reply.send()
├── services/operators.service.js ← { kind, status, body }
├── repositories/operators.repository.js
├── domain/operators.domain.js
└── view/                          ← local ao módulo (v8) — nasce e permanece aqui
    ├── pages/
    │   ├── list/   index.ejs + style.css (.rise-page-operators-list) + script.js
    │   └── detail/ index.ejs + style.css (.rise-page-operators-detail) + script.js
    └── components/
        └── sidebars/new/    index.ejs + style.css + script.js

src/views/components/menus/left/index.ejs   ← item /operators, se escolhido no wizard (sempre global)

tests/unit/operators/operators.service.test.js

O trecho de registro no server.js é copiado automaticamente para o clipboard. Quando a opção de menu é ativada, o item do módulo também é inserido no menu lateral existente. O sidebar nasce local ao módulo operators — só sai para src/views/components/ se um segundo módulo passar a usá-lo (comando Promover para Global).


🧩 Comandos Completos

Todos os comandos estão disponíveis via Ctrl+Shift+P e no menu de contexto do Explorer (botão direito em qualquer pasta).

Comando Descrição
Rise: Inicializar Projeto Gera a estrutura completa com auth JWT
Rise: Novo Módulo Completo ✨ Wizard guiado com pages, sidebars opcionais e inclusão automática no menu lateral
Rise: Novo Módulo Camadas de negócio sem seleção de pages
Rise: Nova Page index.ejs + style.css + script.js
Rise: Novo Componente Modal, sidebar ou component genérico
Rise: Novo Partial Fragmento EJS puro em partials/
Rise: Validar Arquivo Verifica conformidade do arquivo aberto, incluindo isolamento entre módulos (Seção 14)
Rise: Gerar Teste E2E 🧪 Gera teste Playwright a partir do index.ejs
Rise: Atualizar Explorer Refresh manual do Rise Explorer
Rise: Gerar Teste Playwright Gera .spec.ts a partir do script.js do componente (botão direito na pasta)
Rise: Promover para Global 🌐 Botão contextual no Rise Explorer, só em component/partial local a um módulo — move para src/views/ e reescreve o include() de todo consumidor
Rise: Executar arquivo .spec Extrai .claude/skills/, .specs/ e docs/ de um .spec do SpecForge no projeto já aberto

🤖 Uso por Agentes de IA (CLI headless)

Os comandos acima rodam dentro do VS Code (Command Palette, prompts interativos). Para automações, scripts e assistentes de IA que operam via terminal (Bash/PowerShell) — sem UI de editor —, a extensão também expõe um CLI headless: bin/rise-cli.js.

O CLI não é uma reimplementação: ele chama exatamente a mesma lógica de geração, validação, formatação e teste E2E usada pelos comandos da extensão (src/core/generators.js, src/core/validator.js, src/core/formatter.js, src/core/e2e-generator.js), trocando os prompts (showInputBox/showQuickPick) por flags. O resultado gerado é idêntico ao do wizard no editor.

# Inicializar um projeto (--nav inclui menu top + left)
node bin/rise-cli.js init --path ./meu-projeto --name MeuSistema --nav

# Gerar um módulo completo
node bin/rise-cli.js new-module --path ./meu-projeto --name operators

# Gerar page, component e partial
node bin/rise-cli.js new-page      --path ./meu-projeto --module operators --page detail
node bin/rise-cli.js new-component --path ./meu-projeto --category modals --name confirm-delete
node bin/rise-cli.js new-partial   --path ./meu-projeto --name status-badge

# Validar conformidade de um arquivo (equivalente a "Rise: Validar Arquivo")
node bin/rise-cli.js validate ./meu-projeto/src/views/components/modals/confirm-delete/style.css

# Formatar um .ejs (equivalente ao formatador de documento do editor)
node bin/rise-cli.js format ./meu-projeto/src/views/components/modals/confirm-delete/index.ejs
# --check só verifica (exit 1 se precisar formatar), sem escrever — útil em CI.
# Recebe um arquivo por chamada; para formatar vários, itere no shell:
#   for f in $(find ./meu-projeto/src/views -name '*.ejs'); do node bin/rise-cli.js format "$f" --check || exit 1; done

# Gerar esqueleto de teste E2E Playwright a partir de um index.ejs
node bin/rise-cli.js generate-e2e ./meu-projeto/src/modules/operators/view/pages/detail/index.ejs --path ./meu-projeto

# Migrar um projeto v7 (src/views/pages/[mod]/) para o layout v8 (src/modules/[mod]/view/pages/)
node bin/rise-cli.js migrate --module operators --path ./meu-projeto            # dry-run (padrão) — só reporta o plano
node bin/rise-cli.js migrate --module operators --path ./meu-projeto --apply    # grava — exige git limpo
node bin/rise-cli.js migrate --all --confirm --path ./meu-projeto --apply       # projeto inteiro, com confirmação extra

migrate recusa --apply fora de um repositório git ou com o working tree sujo — o rollback é inteiramente delegado ao git (git checkout -- <caminho> / git clean -fd <pages migradas>, ambos impressos ao final do comando). Reescreve include() internos e reply.render()/reply.renderPublic() dos controllers do módulo migrado, e reporta como "candidato à promoção manual" qualquer component/partial que a migração descobrir ser usado por um único módulo.

Promoção (Rise: Promover para Global) só existe no editor — é a única ação de escrita da extensão sem equivalente no CLI headless, por decisão de design: a lista de consumidores afetados é sempre revisada por uma pessoa antes de confirmar, então a operação não foi exposta como flag automatizável.

Todo comando aceita --json, que troca a saída humana por uma linha JSON estruturada em stdout ({ ok, filesCreated, ... } ou { ok, diagnostics }), pensada para ser parseada por um agente em vez de lida por uma pessoa. Códigos de saída seguem convenção Unix: 0 sucesso, 1 erro/violação — validate falha em 1 só se houver diagnóstico de severidade error, a menos que --strict seja passado (aí qualquer diagnóstico, incluindo warning, falha o comando).

Para descobrir comandos e flags disponíveis sem ler o código-fonte:

node bin/rise-cli.js manifest   # schema completo em JSON
node bin/rise-cli.js help       # lista curta, texto simples

O pacote também declara "bin": {"rise-cli": "./bin/rise-cli.js"} no package.json, então em um checkout com npm install o comando fica disponível como npx rise-cli <comando>.


🗂️ Arquitetura Shell · Page · Component · Partial

┌──────────────────────────────────────────────────────────────────────────┐
│  REQUEST HTTP                                                            │
│    ↓                                                                     │
│  Fastify Route → preHandler (Guard) → Controller                         │
│    ↓                                                                     │
│  Service (lógica pura)                                                   │
│    ↓                                                                     │
│  Repository (Sequelize)                                                  │
│    ↓                                                                     │
│  reply.render(page, dados)                                               │
│    ↓                                                                     │
│    SHELL — src/views/index.ejs                                           │
│    Assets globais de public/css/ e public/js/                            │
│                                                                          │
│        PAGE — modules/[mod]/view/pages/[pag]/index.ejs                   │
│        <style><%- include('./style.css') %></style>                      │
│                                                                          │
│        <%- include('views/components/modals/detail/index.ejs') %>        │
│        <%- include('../../components/sidebars/new/index.ejs') %>         │
│        <%- include('views/partials/_page-header.ejs') %>                 │
│                                                                          │
│        <script><%- include('./script.js') %></script>                    │
│    ↓                                                                     │
│  HTML COMPLETO entregue ao browser (sem hydration, sem runtime)          │
└──────────────────────────────────────────────────────────────────────────┘

Acima: views/... sempre acessa algo já global (promovido); ./ e ../../... sempre resolvem contra o arquivo atual — nesse caso, um sidebar que ainda não foi promovido, local ao mesmo módulo [mod]. Ver 🔒 Isolamento entre Módulos para quando cada forma é permitida.

Regras de cada camada

Camada Localização Tem style.css? Tem script.js? Prefixo CSS Namespace JS Pode ser promovida?
Shell src/views/index.ejs — (usa public/) — (usa public/) — — N/A (único)
Page src/modules/[mod]/view/pages/ ✅ Próprio ✅ Próprio .rise-page-[mod]-[pag] window.Rise.Pages.* ❌ Nunca
Component Nasce em src/modules/[mod]/view/components/ · promove p/ src/views/components/ ✅ Próprio ✅ Próprio .rise-[cat]-[nome] window.Rise.[Cat].* ✅ No 2º módulo que usar
Partial Nasce em src/modules/[mod]/view/partials/ · promove p/ src/views/partials/ ❌ Herda ❌ Herda Classes livres — ✅ No 2º módulo que usar

Derivação automática de convenções

modules/operators/view/components/modals/detail/     →  .rise-modal-detail
                                                       →  window.Rise.Modals.Detail

modules/operators/view/components/sidebars/user-new/ →  .rise-sidebar-user-new
                                                       →  window.Rise.Sidebars.UserNew

modules/operators/view/pages/detail/                  →  .rise-page-operators-detail
                                                       →  window.Rise.Pages.OperatorsDetail

A extensão nunca pede ao desenvolvedor que defina o prefixo CSS ou namespace. Eles são calculados a partir da categoria/nome do component (ou módulo/page), não de onde o arquivo mora — por isso o prefixo e o namespace de um component não mudam quando ele é promovido de src/modules/operators/view/components/modals/detail/ para src/views/components/modals/detail/: a promoção move o arquivo, nunca reescreve seu conteúdo interno.


🔒 Isolamento entre Módulos

A regra central da v8: dado o nome de qualquer artefato, sua localização é derivável por uma única pergunta — "é usado por mais de um módulo?". Se sim, mora em src/views/. Se não, mora dentro de src/modules/[mod]/view/. Não existe terceira opção — e não existe acesso direto legítimo de um módulo ao view/ de outro. A resposta correta para essa necessidade é sempre promover, nunca referenciar entre módulos.

src/modules/operators/view/pages/detail/index.ejs

✅ <%- include('./style.css') %>                                     → mesma page, sempre permitido
✅ <%- include('../../components/sidebars/new/index.ejs') %>         → dot-relative que FICA em operators/view/
✅ <%- include('views/partials/_page-header.ejs') %>                 → prefixo views/, acesso global já promovido
✅ <%- include('modules/operators/view/partials/_row.ejs') %>        → prefixo modules/, aponta pro PRÓPRIO módulo

❌ <%- include('modules/documents/view/partials/_row.ejs') %>        → outro módulo direto — violação
❌ <%- include('../../../documents/view/pages/list/index.ejs') %>    → dot-relative que ESCAPA de operators/view/ — violação
Camada Isolamento de CSS/JS próprio? Severidade da violação
Partial Nenhum — herda CSS/JS de quem inclui 🔴 Erro (sempre bloqueia)
Component / Page Parcial — via prefixo CSS e namespace JS ⚠️ Aviso

A regra rise/cross-module (ver 🔒 Linter Embutido) e o diagnóstico ao vivo do validador aplicam exatamente essa lógica — comparando o caminho resolvido do include() (não o texto bruto) contra a raiz view/ do módulo atual, então um ../ que dá várias voltas mas continua dentro do mesmo módulo nunca é sinalizado.


🎨 Highlight EJS

A extensão registra o EJS como linguagem própria com uma grammar TextMate completa. Não é necessária nenhuma configuração adicional.

<%  código JS sem output  %>   ← keyword (laranja/amarelo)
<%= output escapado       %>   ← keyword escaped (verde)
<%- output HTML/unescaped %>   ← keyword unescaped (azul)
<%# comentário EJS        %>   ← comment (cinza)

Antes da extensão:

❌  <script><%-  include('./script.js') %></script>
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              Erro de sintaxe sublinhado em vermelho

Depois da extensão:

✅  <script><%- include('./script.js') %></script>
    ← HTML colorido normalmente, tags EJS coloridas corretamente

O autoclose está configurado: ao digitar <%, o VS Code fecha com %> automaticamente.


✅ Validador e Code Actions

O validador analisa arquivos Rise ao abrir e ao salvar, exibindo diagnósticos diretamente no editor.

Arquivo Problema detectado Severidade
style.css Classe .rise-* com prefixo diferente do esperado ⚠️ Aviso
script.js Ausência de IIFE 🔴 Erro
script.js window.X fora de window.Rise.* ⚠️ Aviso
index.ejs (component) Falta include('./style.css') ⚠️ Aviso
index.ejs (component) Falta include('./script.js') ⚠️ Aviso
index.ejs (component) Sem bloco de documentação de variáveis ℹ️ Info
_partial.ejs Presença de <style> ou <script> próprios ⚠️ Aviso
*.ejs em src/modules/[mod]/view/** include() cross-module — escapa da view/ do próprio módulo 🔴 Erro em partial · ⚠️ Aviso em component/page

Code Actions — Correções com um clique (💡)

Diagnóstico Correção automática
Falta include('./style.css') Insere no topo do arquivo
Falta include('./script.js') Insere no final do arquivo
Sem documentação de variáveis Insere template <%# Variáveis esperadas %>
script.js sem IIFE Envolve todo o conteúdo em IIFE automaticamente
window.MinhaVar = ... Renomeia para window.Rise.MinhaVar

🔍 Hover e Go to Definition

Hover (passe o mouse)

Em .ejs — sobre um include():

╔════════════════════════════════════════════╗
║  Rise — Component                          ║
║  Pasta: modals/detail                      ║
║  CSS:   .rise-modal-detail                 ║
║  JS:    window.Rise.Modals.Detail          ║
║                                            ║
║  Variáveis esperadas:                      ║
║  - title: string                           ║
║  - contentHtml: string                     ║
╚════════════════════════════════════════════╝

Em .js — sobre window.Rise.Modals.Detail:

╔════════════════════════════════════════════╗
║  Rise — window.Rise.Modals...              ║
║                                            ║
║  API pública:                              ║
║  - open()                                  ║
║  - close()                                 ║
║                                            ║
║  [Abrir script.js]                         ║
╚════════════════════════════════════════════╝

Go to Definition (Ctrl+Click)

Contexto Comportamento
include('./components/modals/detail/index.ejs') Abre o arquivo incluído
include('./partials/_page-header.ejs') Abre o partial
window.Rise.Modals.Detail Abre o script.js na linha da API pública
window.Rise.Sidebars.UserNew Localiza e abre o script.js da sidebar

🧪 Gerador de Teste E2E

Com qualquer index.ejs de component ou page aberto:

Ctrl+Shift+P → Rise: Gerar Teste E2E 🧪

A extensão extrai automaticamente do template:

  • IDs de elementos → page.locator('#id')
  • data-attributes → page.locator('[data-*]')
  • Classes .rise-* → page.locator('.rise-*')
  • Campos de formulário → page.fill('[name="campo"]', ...)
  • Namespace window.Rise → chamadas diretas no teste

Testes gerados por tipo:

Tipo Casos de teste gerados
Modal Oculto por padrão, open(), close(), ESC, clique no backdrop
Sidebar Oculto por padrão, open(), close(), ESC, botão de fechar
Page Renderização, submit de formulário, clique em item de lista
Component Presença no DOM com seletores comentados

O arquivo é salvo em tests/e2e/ espelhando o caminho do artefato e aberto automaticamente no editor.


📦 SpecForge — Importar arquivo .spec

O SpecForge é a ferramenta de especificação do ecossistema Rise. Ele exporta arquivos .spec (ZIPs renomeados) contendo .claude/skills/, .specs/changes/ e docs/.

Ctrl+Shift+P → Rise: Inicializar Projeto → 📦 Importar arquivo .spec

O file picker filtra apenas arquivos .spec. Após a extração, o .spec é deletado automaticamente — nenhum rastro fica no projeto.

Estrutura extraída:

projeto/
├── .claude/skills/          ← Skills de arquitetura para o agente AI
├── .specs/
│   ├── changes/             ← Changes prontos para execução
│   └── executar_todas.md    ← Cole no Claude para iniciar
└── docs/                    ← Documentação do projeto

🧪 Gerar Teste Playwright

Botão direito na pasta do componente → Rise: Gerar Teste Playwright

A extensão lê o script.js, extrai os métodos da API pública e gera um .spec.ts completo em tests/e2e/components/[categoria]/[nome].spec.ts.

Exemplo — dado este script.js:

window.Rise.Modals.Detalhe = {
  open:   open,
  close:  close,
  reload: reload,
};

Gera automaticamente:

  • Teste de renderização do elemento raiz (#rise-modal-detalhe)
  • Teste de registro do namespace window.Rise.Modals.Detalhe
  • Um teste para cada método: open(), close(), reload()

Com módulo de domínio (para evitar conflito entre módulos):

User   → window.Rise.User.Modals.Detalhe
Pedidos → window.Rise.Pedidos.Modals.Detalhe

Para rodar os testes:

npm run dev              # servidor deve estar rodando
npm run test:e2e         # headless
npm run test:e2e:ui      # modo visual
npm run test:e2e:headed  # browser visível

O playwright.config.ts é gerado com baseURL lida automaticamente do .env (sem configuração manual).


🔒 Linter Embutido

O projeto gerado inclui plugins de linting que rodam ao salvar, exibindo erros no painel Problems com sublinhados no código.

ESLint — Regras Rise

Regra O que detecta Severidade
rise/iife script.js sem IIFE ou sem 'use strict' 🔴 Erro
rise/namespace Namespace errado, guard ausente, window.X fora do window.Rise 🔴 Erro
rise/cross-module include() em .ejs que escapa da view/ do próprio módulo (Seção 14) 🔴 Erro em view/partials/** · ⚠️ Aviso em view/{pages,components}/**

rise/cross-module roda sobre .ejs, que não é JavaScript — o eslint.config.js gerado registra um parser "no-op" (tools/eslint-plugin-rise/ejs-noop-parser.js) só para os blocos de files que apontam pra .ejs, evitando que o espree padrão quebre na sintaxe <% %>. A regra em si lê o texto bruto do arquivo e aplica a mesma lógica (e a mesma resolução de caminho) do diagnóstico ao vivo do validador — dois pontos de aplicação, uma única fonte de verdade sobre o que conta como violação.

Stylelint — Regras Rise

Regra O que detecta Severidade
rise/css-prefix Classe CSS sem o prefixo .rise-[categoria]-[nome] 🔴 Erro
npm run lint       # ESLint nos script.js e .ejs de módulos
npm run lint:css   # Stylelint nos style.css de componentes

Os plugins ficam em tools/eslint-plugin-rise/ e tools/stylelint-plugin-rise/ — embutidos no projeto gerado, sem dependência externa própria (eslint/stylelint em si são devDependencies normais do package.json gerado, como jest/playwright).


📝 Snippets EJS

Digite o prefixo em qualquer arquivo .ejs e pressione Tab.

Prefixo O que gera
rise-shell Shell HTML completo com head, body, CSS/JS globais e include(pageComponent)
rise-page Page com include de style.css e script.js, div com prefixo
rise-component Component encapsulado com role e aria-label
rise-modal Modal completo: backdrop, container, header, body, footer
rise-sidebar Sidebar/offcanvas: backdrop, panel, header, body, botão de fechar
rise-include <%- include('caminho', { chave: valor }) %> com placeholders
rise-partial <%- include('partials/_nome', { dados }) %>
rise-each <% items.forEach(function(item) { %> ... <% }); %>
rise-if <% if (condition) { %> ... <% } else { %> ... <% } %>
rise-local <% if (locals.variavel) { %> ... <% } %>
rise-flash Bloco completo de flash messages (success, error, info)
rise-empty Condicional de empty state com include do partial
rise-pagination Include do partial de paginação com currentPage e totalPages

📝 Snippets JavaScript

Digite o prefixo em qualquer arquivo .js e pressione Tab.

Prefixo O que gera
rise-iife IIFE base com window.Rise, getElementById, funções privadas e API pública
rise-iife-modal IIFE completa de modal: open(data), close(), ESC, backdrop, CustomEvents
rise-iife-sidebar IIFE completa de sidebar: open(), close(), ESC, botões
rise-iife-page IIFE base de page com window.Rise.Pages.[Nome] e refresh()
rise-dispatch document.dispatchEvent(new CustomEvent('comp:acao', { detail }))
rise-listen document.addEventListener('comp:acao', function(e) { })
rise-service Método async com try/catch e retorno { kind, status, body }
rise-ok return { kind: 'json', status: 200, body: { data } }
rise-err return { kind, status: 4xx/5xx, body: { erro } } com seleção de status
rise-controller Handler SSR Fastify com verificação de out.status, flash e reply.render()
rise-api Handler JSON Fastify com reply.status(out.status).send(out.body)
rise-plugin Two-Plugin Factory completo: viewPlugin + apiPlugin + guard hook
rise-repo Método de Repository com Sequelize findAll, where e order
rise-migration Migration Umzug com up/down e seleção de operação SQL
rise-migration-table Migration createTable completa com id, coluna, timestamps
rise-migration-col Migration addColumn com tipo, allowNull, defaultValue
rise-fetch-modal fetch() + window.Rise.Modals.[Nome].open() com tratamento de erro
rise-e2e Teste E2E Playwright base com beforeAll, afterAll e it()
rise-e2e-modal Teste E2E completo de modal com casos reais

📊 Rise Explorer

Um painel dedicado na Activity Bar do VS Code com mapa visual do projeto.

RISE EXPLORER
├── 🌐 Globais (src/views/)
│   ├── 📄 Pages
│   │   └── home
│   ├── 🧩 Components
│   │   ├── menus/left      ← sempre global
│   │   └── modals/detail   → .rise-modal-detail (promovido — usado por 2+ módulos)
│   └── 🧱 Partials
│       ├── _page-header.ejs
│       ├── _empty-state.ejs
│       ├── _pagination.ejs
│       └── _alert-flash.ejs
│
└── 📦 Módulos
    ├── auth
    │   └── 📄 Pages › login  → index.ejs · style.css · script.js  (clicáveis)
    └── operators
        ├── 📄 Pages
        │   ├── list    → .rise-page-operators-list
        │   └── detail  → .rise-page-operators-detail
        ├── 🧩 Components
        │   └── sidebars/new  → .rise-sidebar-new  🌐 Promover para Global
        └── 🧱 Partials

Um artefato nunca aparece nas duas seções ao mesmo tempo: local a um módulo (sob 📦 Módulos) ou global (sob 🌐 Globais), nunca ambos. Só módulos com pasta view/ aparecem em 📦 Módulos — um módulo puramente de backend (sem nenhuma page/component/partial) não gera um nó vazio. O botão contextual 🌐 Promover para Global aparece só em component/partial local — nunca em page (que nunca é promovida) e nunca em algo já global. O painel atualiza automaticamente ao salvar, criar ou deletar arquivos. O botão ✨ no header abre o Wizard diretamente.


🏗️ Casos de Uso

Tipo de projeto Como a extensão ajuda
Sistema administrativo Wizard gera cada módulo CRUD em < 1 min; guard por role pronto para usar
Portal SSR corporativo Shell único, partials reutilizáveis, Rise Explorer para navegação
E-commerce Módulos independentes por domínio; modal de detalhe e sidebar de filtro prontos
API Enterprise Two-Plugin Factory separa rotas SSR e JSON no mesmo módulo
Sistema governamental requireRole() por feature; ARIA completo nos components gerados
SaaS multi-tenant Chaves rise_local/dev/hmg/prd geradas por ambiente

⚙️ Configurações

Configuração Valores Padrão
rise.framework fastify | express fastify

📋 Changelog

v1.0.0 — Lançamento · Arquitetura Rise v8

  • ✅ View local ao módulo — Novo Módulo/Nova Page/Novo Componente/Novo Partial passam a gerar em src/modules/[mod]/view/{pages,components,partials}/, não mais direto em src/views/; src/views/ fica reservado ao que é global (Shell, e o que já foi promovido)
  • ✅ view.plugin.js com includer — resolve modules/... e views/... a partir de src/, mantendo .//../ file-relative como já era no EJS; nenhum projeto v7 existente quebra, já que o comportamento antigo continua sendo o fallback
  • ✅ Promover para Global 🌐 — novo comando/botão contextual no Rise Explorer: move um component/partial local para src/views/ na primeira vez que um segundo módulo precisa dele, reescrevendo o include() de todo consumidor automaticamente
  • ✅ Isolamento entre módulos (Seção 14) — novo diagnóstico do validador e nova regra ESLint rise/cross-module: um include() que escapa da view/ do próprio módulo é sinalizado (erro em partial, aviso em component/page); ver 🔒 Isolamento entre Módulos
  • ✅ rise-cli migrate — migra um projeto v7 existente módulo a módulo (ou --all --confirm), com --dry-run como padrão e rollback delegado ao git (recusa --apply fora de um repo git ou com working tree sujo)
  • ✅ Rise Explorer reagrupado — raiz agora separa "🌐 Globais" de "📦 Módulos"; cada módulo com pasta view/ ganha suas próprias seções de Pages/Components/Partials
  • ✅ Hover / Go to Definition / Gerar Teste E2E — passam a localizar script.js/component tanto em src/views/ (global) quanto em cada src/modules/[mod]/view/ (local), priorizando o global quando o mesmo nome existir nos dois lugares
  • ✅ npm run lint cobre .ejs de módulo — antes só varria script.js; sem isso a regra rise/cross-module nunca seria de fato executada via npm run lint (o ESLint só analisa o que recebe na CLI, o files de um bloco do config filtra dentro disso, não expande a varredura)

v0.8.0

  • ✅ CLI headless (bin/rise-cli.js) — os comandos de geração/validação/formatação/teste E2E passam a ser chamáveis via terminal (Bash/PowerShell), sem depender da UI do VS Code; pensado para uso por agentes de IA e scripts. Ver 🤖 Uso por Agentes de IA
  • ✅ Comandos format e generate-e2e no CLI — formatação de .ejs (com --check para uso em CI) e geração de esqueleto de teste E2E Playwright, ambos agora disponíveis fora do editor
  • ✅ src/core/ — lógica de geração (generators.js), validação (validator.js), formatação (formatter.js) e geração de teste E2E (e2e-generator.js) extraída para módulos puros, sem dependência de vscode; extensão e CLI agora consomem a mesma implementação
  • ✅ Testes com renderização real de EJS — test/unit/ejs-render.test.js compila todo .ejs gerado com o motor ejs de verdade, fechando uma lacuna que antes só validava conteúdo gerado como string

v0.7.0

  • ✅ Novo Módulo Completo aprimorado — wizard agora pergunta se o módulo deve ser adicionado ao menu lateral
  • ✅ Menu lateral automático — cria ou atualiza src/views/components/menus/left/index.ejs com label e rota do módulo
  • ✅ Detalhe como page — fluxo completo prioriza detail como página, não como modal gerado automaticamente
  • ✅ Sidebars integradas às pages — pages criadas recebem botões simples para abrir os sidebars selecionados
  • ✅ Títulos nos artefatos gerados — pages e sidebars nascem com títulos visíveis e consistentes
  • ✅ Correções de bugs e refinamentos de fluxo — ajustes no wizard para reduzir passos manuais após criar um módulo

v0.6.0

  • ✅ Gerar Teste Playwright — botão direito na pasta do componente gera .spec.ts com testes por método
  • ✅ Importar arquivo .spec — integração com SpecForge no comando Inicializar Projeto
  • ✅ Playwright configurado — playwright.config.ts gerado com baseURL lida do .env
  • ✅ Scripts npm E2E — test:e2e, test:e2e:ui, test:e2e:headed adicionados
  • ✅ Linter CSS embutido — Stylelint com regra rise/css-prefix
  • ✅ Linter JS embutido — ESLint com regras rise/namespace e rise/iife
  • ✅ Namespace com módulo de domínio — suporte a window.Rise.User.Modals.Detalhe
  • ✅ SQL injection corrigido — Repository.js valida tableName no construtor
  • ✅ Umzug + Sequelize + sqlite3 — adicionados ao package.json gerado
  • ✅ write() com aviso — alerta quando arquivo já existe em vez de ignorar silenciosamente

v0.5.0

  • ✅ EJS Formatter — Shift+Alt+F formata .ejs preservando tags EJS intactas
  • ✅ Code Actions (💡) — correções automáticas para todos os diagnósticos
  • ✅ Gerador de Teste E2E — Playwright gerado a partir do template .ejs
  • ✅ Hover com documentação — assinatura de components e window.Rise.*
  • ✅ Go to Definition — Ctrl+Click em include() e window.Rise.*
  • ✅ Novos snippets: rise-e2e, rise-e2e-modal

v0.4.0

  • ✅ Rise Explorer — painel lateral com mapa visual arquitetural
  • ✅ Wizard de módulo completo — fluxo guiado com seleção de pages e components
  • ✅ Snippets de migration: rise-migration, rise-migration-table, rise-migration-col
  • ✅ Novo comando: Rise: Novo Partial

v0.3.0

  • ✅ Validador em tempo real — DiagnosticCollection com regras de conformidade
  • ✅ Highlight EJS — grammar TextMate própria para .ejs
  • ✅ Novo comando: Rise: Validar Arquivo

v0.2.0

  • ✅ Estrutura atualizada para Rise v7.0 (Fastify)
  • ✅ Inicializar Projeto gera auth JWT completo com módulo, model, migration e seeder
  • ✅ Chaves de ambiente geradas dinamicamente: rise_local_*, rise_dev_*, rise_hmg_*, rise_prd_*
  • ✅ 14 snippets EJS e 17 snippets JS
  • ✅ Plugin factory, controllers, services, repositories e domain gerados
  • ✅ Novo comando: Rise: Novo Partial

v0.1.0

  • ✅ Comandos básicos: Inicializar Projeto, Novo Módulo, Novo Componente, Nova Page
  • ✅ Geração de Plugin Factory, Controller, Service, Repository, Domain
  • ✅ Suporte a Express

🔗 Recursos

  • Documentação completa da arquitetura Rise
  • Reportar um problema
  • Eduardo de Freitas Arantes

Feito com ♥ por Eduardo de Freitas Arantes

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft