Communitygithub.com

aubarcito48/portfolio

Extrair HTML estático autocontido de uma aplicação web compilada ou de componentes React, incorporando CSS e imagens. Use esta habilidade sempre que precisar capturar um estado específico da UI, compartilhar uma versão estática de uma página ou preparar assets para upload no Stitch, mesmo que o usuário apenas peça para 'salvar o HTML' ou 'simular a visualização'.

O que é portfolio?

Esta habilidade permite extrair um arquivo HTML estático e autocontido de qualquer aplicação web, incorporando todo o CSS e imagens como dados base64. Ela oferece duas estratégias principais: a Estratégia A (Puppeteer) é a recomendada para a maioria dos casos, pois captura o DOM renderizado com estilos computados e funciona com qualquer framework. A Estratégia B (Subagente de Navegador) é ideal quando é necessário interagir com a página antes da captura (como clicar em botões ou preencher formulários). A habilidade também inclui um fallback estático (MockPage.jsx) para situações em que a aplicação não pode ser executada localmente. Compatível com React, Next.js, Angular, Vue, Svelte e Storybook, ela resolve automaticamente problemas comuns como lazy loading, modo escuro, fontes de ícones e gráficos canvas, garantindo um HTML fiel ao original.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/aubarcito48/portfolio/tree/HEAD/.agents/skills/stitch-extract-static-html

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Extrair HTML Estático

Extrai um arquivo HTML estático autocontido de qualquer aplicação web.

Qual Estratégia Usar

Você DEVE perguntar ao usuário qual estratégia usar antes de prosseguir. Apresente as opções claramente, recomende a Estratégia A como padrão preferido e forneça um breve resumo de prós e contras para cada opção para ajudá-los a tomar uma decisão informada.

Estratégia A (Puppeteer)Estratégia B (Subagente de Navegador)
QuandoA aplicação roda localmente, sem barreira de autenticaçãoPrecisa interagir com a página primeiro (clicar, preencher formulários)
FidelidadeA maior — estilos computados resolvidosAlta — DOM renderizado
ConfiguraçãoZero — nenhum mock necessárioZero — nenhum mock necessário
FrameworkQualquerQualquer
SaídaGrava em arquivo — sem limite de tamanhoPode truncar no contexto do agente

[!WARNING] Ponto de Verificação — Confirmação do Usuário Necessária. Você DEVE perguntar ao usuário qual estratégia ele prefere antes de prosseguir. Apresente a tabela de comparação acima, recomende a Estratégia A como padrão e aguarde aprovação explícita. NÃO tome a decisão sozinho nem prossiga até que o usuário confirme.


Estratégia A: Instantâneo com Puppeteer (Recomendado)

Inicia o Chrome headless, captura o DOM totalmente renderizado e produz um arquivo HTML autocontido com todo o CSS embutido e imagens como base64. Funciona com qualquer framework — não precisa de MockPage.jsx.

Pré-requisitos

  • Aplicação rodando localmente (ex.: npm run dev)
  • Node.js com puppeteer disponível (verificar: node -e "require('puppeteer')")

Fluxo de Trabalho

  1. Inicie a Aplicação e anote a porta.

    [!WARNING] Ponto de Verificação — Confirmação do Usuário Necessária. Após iniciar o servidor local, você DEVE pausar e pedir confirmação ao usuário antes de executar o script de instantâneo ou iniciar um subagente de navegador. Informe a URL e a porta ao usuário para que ele possa verificar se a aplicação está rodando e renderizando corretamente. NÃO prossiga para a etapa de instantâneo até que o usuário confirme.

  2. Execute o Script de Instantâneo:

    npx tsx <SKILL_DIR>/scripts/snapshot.ts \
      --url http://localhost:5173 \
      --output .stitch/home.html \
      --wait 2000
    
  3. Múltiplas páginas — execute uma vez por rota:

    npx tsx <SKILL_DIR>/scripts/snapshot.ts \
      --url http://localhost:5173 --output .stitch/home.html --wait 2000
    npx tsx <SKILL_DIR>/scripts/snapshot.ts \
      --url http://localhost:5173/pricing --output .stitch/pricing.html --wait 2000
    npx tsx <SKILL_DIR>/scripts/snapshot.ts \
      --url http://localhost:5173/dashboard --output .stitch/dashboard.html --wait 2000 --html-class dark
    
  4. Limpe o Servidor de Desenvolvimento: Se um servidor de desenvolvimento local foi iniciado especificamente para a extração do instantâneo, certifique-se de parar o processo do servidor ou encerrar a tarefa em segundo plano assim que a extração for concluída.

Flags do Script

FlagPadrãoDescrição
--url(obrigatório)URL a ser capturada
--output(obrigatório)Caminho do arquivo de saída
--wait1000Espera extra (ms) após a rede ficar ociosa. Aumente para aplicações com carregamento preguiçoso.
--viewport1280x800Tamanho da viewport como LARGURAxALTURA
--html-class—Classe(s) para o elemento <html> (ex.: dark)
--remove-fixedfalseRemove elementos fixos/sticky (banners de cookie, widgets de chat)
--full-heightfalseRedimensiona a viewport para a altura total de rolagem
--title—Sobrescreve o título da página (definir como o caminho da rota, ex. /dashboard ou /settings/profile)
--auth-script—Caminho para um módulo JS/TS que exporta uma função async (page) => void padrão para autenticação
--inline-canvasfalseConverte elementos <canvas> (ECharts, Chart.js, D3) para tags <img> base64

O Que Ele Faz Automaticamente

  • Captura todas as regras CSSOM de document.styleSheets (preserva estilos dinâmicos de desenvolvimento Vite/Tailwind e CSS-in-JS)
  • Embuti todos os <link rel="stylesheet"> → blocos <style>
  • Converte src de <img> e srcset → URIs de dados base64 (ignora fontes externas)
  • Embuti arquivos de fontes de ícones (@font-face) de mesma origem e relativos como URIs de dados base64 para que ligaduras nunca sejam renderizadas como texto ASCII
  • Embuti URLs de <source srcset> como base64
  • Remove entradas srcset com falha/mortas para que o navegador use o src embutido como fallback
  • Remove tags <script>, blocos de estilo de desenvolvimento Vite HMR (createHotContext, import.meta.hot) e sobreposições de desenvolvimento
  • Resolve caminhos relativos de url() em CSS antes de embutir

Notas por Framework

FrameworkNotas
React + ViteFunciona imediatamente. --wait 1000.
Next.js--wait 3000 para hidratação SSR. URL: http://localhost:3000. <img srcset> de /_next/image é automaticamente embutido como base64.
Angular (@angular/cli / v17+)Funciona imediatamente com ng serve (URL padrão: http://localhost:4200). --wait 2000 para hidratação de animação do Angular Material / PrimeNG e rotas carregadas preguiçosamente.
Vue / NuxtFunciona imediatamente.
Svelte / SvelteKitFunciona imediatamente.
StorybookUse a URL da história: --url http://localhost:6006/?path=/story/...
SSR (Webpack)Pode precisar de --wait maior.

Solução de Problemas

ProblemaSolução
Imagens ausentesAumente --wait
Imagens aparecem quebradas após o servidor pararVerifique se srcset foi embutido — veja o log para "Imagens embutidas: N". Se as URLs de srcset falharam, elas são removidas automaticamente para que src (embutido) seja usado.
Ícones exibidos como texto / Fonte serifa sem estiloCertifique-se de que snapshot.ts captura CSSOM de document.styleSheets (passo 0) e que fontes de ícones de mesma origem (@font-face) são embutidas como URIs de dados base64.
/_next/image do Next.js não embutidoCertifique-se de que o servidor de desenvolvimento está rodando quando o instantâneo é executado — o script busca imagens otimizadas do servidor em execução.
Modo escuro não aplicado--html-class dark
Banner de cookie na saída--remove-fixed
Página requer loginUse --auth-script ./auth.ts (veja Páginas com Autenticação abaixo)
Gráficos/plotagens mostrados como caixas em brancoUse --inline-canvas para serializar <canvas> para <img> base64
Cannot find module 'puppeteer'npm install -g puppeteer

Páginas com Autenticação

Para aplicações com guardas de login (Vue Router beforeEach, React ProtectedRoute, etc.), crie um pequeno script de autenticação que é executado na sessão do Puppeteer:

// auth-myapp.ts
import type { Page } from 'puppeteer';

export default async function authenticate(page: Page) {
  // Exemplo 1: Preencher e enviar um formulário de login
  await page.type('#username', 'admin');
  await page.type('#password', 'password123');
  await page.click('#login-button');
  await page.waitForNavigation({ waitUntil: 'networkidle2' });

  // Exemplo 2: Injetar cookies/localStorage diretamente
  // await page.evaluate(() => {
  //   localStorage.setItem('token', 'mock-jwt-token');
  // });

  // Exemplo 3: Chamar a própria API de login da aplicação via injeção de módulo (Vue/Vite)
  // await page.evaluate(() => {
  //   return new Promise((resolve) => {
  //     const script = document.createElement('script');
  //     script.type = 'module';
  //     script.textContent = `
  //       import { useUserStore } from '/src/store/modules/user.ts';
  //       import { fetchLogin } from '/src/api/auth.ts';
  //       const res = await fetchLogin({ userName: 'Admin', password: '123456' });
  //       useUserStore().setToken(res.token, res.refreshToken);
  //       window.dispatchEvent(new CustomEvent('auth-done'));
  //     `;
  //     document.head.appendChild(script);
  //     window.addEventListener('auth-done', () => resolve(true), { once: true });
  //   });
  // });
}

Em seguida, use-o:

npx tsx <SKILL_DIR>/scripts/snapshot.ts \
  --url http://localhost:5173/#/dashboard \
  --output .stitch/dashboard.html \
  --auth-script ./auth-myapp.ts \
  --inline-canvas \
  --wait 5000

O script navega primeiro para a --url (que pode redirecionar para o login), executa sua função de autenticação e então re-navega para a --url original com a sessão autenticada.


Estratégia B: Captura com Subagente de Navegador

Use quando precisar interagir com a página (clicar em botões, preencher formulários, navegar por abas) antes de capturar. O subagente de navegador oferece controle total, mas a saída pode truncar para páginas grandes.

Fluxo de Trabalho

  1. Inicie a Aplicação localmente.

  2. Navegue usando um subagente de navegador.

  3. Interaja conforme necessário (clicar, rolar, preencher formulários).

  4. Extraia o DOM: document.documentElement.outerHTML

    [!WARNING] Páginas grandes podem truncar. Para lidar com isso:

    • Remova tags <style> antes da extração: document.querySelectorAll('style').forEach(el => el.remove())
    • Re-adicione estilos estaticamente (link CDN do Tailwind, CSS de origem)
  5. Salve em arquivo.


Apêndice: Fallback Estático (MockPage.jsx)

[!NOTE] Este método é um último recurso para quando a aplicação não pode ser executada localmente (dependências quebradas, backend ausente, barreiras de autenticação sem alternativa). Requer achatar manualmente os componentes React em um único arquivo JSX. Prefira a Estratégia A sempre que possível.

Quando Usar

  • A aplicação não pode ser executada localmente
  • A página requer autenticação sem mock/alternativa
  • Você precisa de um estado de UI específico que é impossível de alcançar por navegação (telas de erro, estados vazios)

Referência Rápida

npx tsx <SKILL_DIR>/scripts/extract_inline_html.ts \
  --index-css src/css/App.css \
  --extra-css index.html \
  --outdir .stitch \
  --page src/MockPage.jsx:Page.html:"Título da Página"

Flags principais: --no-tailwind (aplicações não-Tailwind), --html-class dark (modo escuro), --css-files (arquivos CSS extras).

Detecção automática: A configuração do Tailwind é detectada automaticamente. Diretivas @apply usam automaticamente <style type="text/tailwindcss">.

Regras do MockPage.jsx

  1. Inclua o layout completo — cabeçalho, barra lateral, rodapé (leia App.js primeiro)
  2. Achate todos os condicionais — escolha um estado, remova todos os ternários e guardas &&
  3. Codifique todos os dados — substitua {variable} por valores concretos, desenrole loops .map()
  4. Preserve logotipos — use <img> com caminhos locais (o pós-processamento os embutirá)
  5. Remova elementos flutuantes — banners de cookie, widgets de chat, botões de feedback

Pós-Processamento

Embutir imagens locais:

npx tsx <SKILL_DIR>/scripts/post_process.ts \
  .stitch/Page.html --base-dir <diretório-da-aplicação>

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

aubarcito48/portfolio

Transforms vague UI ideas into polished, Stitch-optimized prompts. Enhances specificity, adds UI/UX keywords, injects design system context, and structures output for better generation results.

aubarcito48/portfolio

>- Convert frontend code (Vite, React, Angular, Vue, etc.) to a Stitch Design by chaining static HTML extraction, design system extraction, and file upload. **ALWAYS** use this skill when the user's intent is to move existing web apps or React/Angular/Vue components into Stitch (e.g., requests to "save", "migrate", or "upload"). You must use this skill even for simple "save" operations, as it is the only way to ensure the design system is extracted and assets are properly linked.

aubarcito48/portfolio

>- Extract a comprehensive design system (DESIGN.md) directly from frontend source code — React, Vue, Svelte, Angular, plain HTML/CSS, or any web framework. Analyzes component files, stylesheets, Tailwind configs, theme definitions, and design tokens to produce a rich, Stitch-compatible design system document. Use this skill whenever the user wants to reverse-engineer a design system from an existing codebase, audit the visual language of a project, extract design tokens from source files, or understand the styling patterns in a frontend repo — even if they just say "what does this app look like?" or "pull out the design from this code.

aubarcito48/portfolio

>- Generate new screens from text prompts or images, edit existing screens with prompts and design system tokens, and generate design variants using Stitch MCP. Includes prompt enhancement pipeline, design mappings, professional UI/UX terminology, design tokens and theme system capabilities.

Habilidades Relacionadas