Eu portei JustHTML de Python para JavaScript com Codex CLI e GPT-5.2 em 4,5 horas

Eu portei JustHTML de Python para JavaScript com Codex CLI e GPT-5.2 em 4,5 horas


Eu portei JustHTML de Python para JavaScript com Codex CLI e GPT-5.2 em 4,5 horas

15 de dezembro de 2025

Escrevi sobre JustHTML ontem – o projeto de Emil Stenström para construir um novo analisador HTML5 compatível com padrões em código Python puro usando agentes de codificação executados na abrangente biblioteca de testes html5lib-tests. Ontem à noite, por pura curiosidade, decidi tentar portando JustHTML de Python para JavaScript com o mínimo de esforço possível, usando Codex CLI e GPT-5.2. Funcionou além das minhas expectativas.

DR;TL

Eu construí simonw/justjshtml, uma biblioteca de análise HTML5 livre de dependência em JavaScript que passa em 9.200 testes do conjunto html5lib-tests e imita o design da API da biblioteca JustHTML de Emil.

Foram necessárias duas solicitações iniciais e alguns pequenos acompanhamentos. O GPT-5.2 executado no Codex CLI funcionou ininterruptamente por várias horas, queimou 1.464.295 tokens de entrada, 97.122.176 tokens de entrada em cache e 625.563 tokens de saída e acabou produzindo 9.000 linhas de JavaScript totalmente testado em 43 commits.

Tempo decorrido desde a ideia do projeto até a biblioteca finalizada: cerca de 4 horas, durante as quais também comprei e decorei uma árvore de Natal com a família e assisti ao último filme Knives Out.

Alguns antecedentes

Uma das contribuições mais importantes da especificação HTML5 há dez anos foi a maneira como ela especificou com precisão como inválido HTML deve ser analisado. O mundo está cheio de documentos inválidos e ter uma especificação que cubra esses documentos significa que os navegadores podem tratá-los da mesma maneira – não há mais “comportamento indefinido” com que se preocupar ao criar software de análise.

Não é novidade que essas regras de análise inválidas são bastante complexas! O livro online gratuito Idiossincrasias do analisador HTML, de Simon Pieters, é um excelente mergulho profundo neste tópico, em particular o Capítulo 3. O analisador HTML.

O projeto Python html5lib iniciou o repositório html5lib-tests com um conjunto de testes independentes de implementação. Desde então, eles se tornaram o padrão ouro para testes de interoperabilidade de analisadores HTML5 e são usados ​​​​por projetos como o Servo, que os utilizou para ajudar a construir o html5ever, um “analisador HTML5 de alto desempenho para navegador” escrito em Rust.

O projeto JustHTML de Emil Stenström é uma implementação Python pura de um analisador HTML5 que passa no conjunto completo de testes html5lib. Emil passou alguns meses trabalhando nisso como um projeto paralelo, escolhendo deliberadamente um problema com um conjunto de testes abrangente existente para ver até onde ele poderia chegar com agentes de codificação.

A certa altura, ele fez com que os agentes o reescrevessem com base em uma inspeção minuciosa da biblioteca Rust html5ever. Não sei quanto disso foi tradução direta versus inspiração — o projeto dele tem 1.215 commits no total, então parece ter incluído uma enorme quantidade de iterações, não apenas uma conversão direta.

Meu projeto é uma porta reta. Instruí o Codex CLI a construir uma versão JavaScript do código Python de Emil.

O processo em detalhes

Comecei com um pouco de mise en place. Verifiquei dois repositórios e criei um terceiro diretório vazio:

cd ~/dev
git clone https://github.com/EmilStenstrom/justhtml
git clone https://github.com/html5lib/html5lib-tests
mkdir justjshtml
cd justjshtml

Então iniciei o Codex CLI para GPT-5.2 assim:

Que --yolo flag é um atalho para --dangerously-bypass-approvals-and-sandboxo que é tão perigoso quanto parece.

Meu primeiro prompt disse ao Codex para inspecionar o código existente e usá-lo para construir uma especificação para a nova biblioteca JavaScript:

We are going to create a JavaScript port of ~/dev/justhtml - an HTML parsing library that passes the full ~/dev/html5lib-tests test suite. It is going to have a similar API to the Python library but in JavaScript. It will have no dependencies other than raw JavaScript, hence it will work great in the browser and node.js and other environments. Start by reading ~/dev/justhtml and designing the user-facing API for the new library - create a spec.md containing your plan.

Analisei as especificações, que incluíam um conjunto de marcos propostos, e pedi para adicionar outro:

Add an early step to the roadmap that involves an initial version that parses a simple example document that is valid and returns the right results. Then add and commit the spec.md file.

Aqui está o arquivo spec.md resultante. Minha solicitação para essa versão inicial tornou-se “Milestone 0.5”, que era assim:

Marco 0.5 — Análise de fumaça de ponta a ponta (documento único válido)

  • Implemente a menor fatia de ponta a ponta para que a API pública chegue bem cedo:
    • new JustHTML("

      Hello

      ") retorna uma árvore com a estrutura de tags e nós de texto esperados.

    • doc.toText() retorna "Hello" e doc.errors está vazio para esta entrada válida.
  • Adicionar scripts/smoke.js (sem dependências) que executa o exemplo e afirma a estrutura/saída esperada.
  • Portão: node scripts/smoke.js passa.

Aí eu contei:

Implement Milestone 0.5

E lá foi. O código resultante pareceu funcionar, então eu disse:

Configure GitHub Actions test.yml to run that on every commit, then commit and push

eu corri git init e criei um repositório GitHub privado para este projeto neste ponto e configurei o diretório local para enviar para aquele remoto.

Aqui está o empurrão inicial. Aí eu contei:

OK do the rest, commit and push often

E foi quase isso!

Configurei meu laptop para não adormecer e deixei-o sozinho enquanto saíamos para comprar uma árvore de Natal. O “commit e push frequentemente” significava que eu poderia monitorar seu progresso no meu telefone, atualizando o log de commit no GitHub.

Eu estava executando isso em minha conta ChatGPT Plus de US$ 20/mês, que tem uma janela de permissão de token de cinco horas para Codex CLI. Acabou às 18h35 e o Codex pausou, então esperei até o ponto de reinicialização às 19h14 e digitei:

Keep going

Às 21h30 declarou-se encerrado com a seguinte mensagem resumida:

• What’s Done

  - html5lib-tests now run in CI and pass: tokenizer 6810/6810, tree 1770/1782
    (12 skipped: #script-on), serializer 230/230, encoding 82/83 (1 skipped:
    scripted) (.github/workflows/test.yml:1).
  - Public API expanded: stream() (src/stream.js:1), CSS selectors query()/
    matches() (src/selector.js:1), and toMarkdown() (src/markdown.js:1), all
    exported via src/index.js:1.
  - Added no-deps unit scripts for selectors/stream/markdown (scripts/run-
    selector-tests.js:1, scripts/run-stream-tests.js:1, scripts/run-markdown-
    tests.js:1) and wired them into CI.
  - Fixed TreeBuilder so 
no longer closes

(src/treebuilder.js:647).

Como toque final, adicionei uma interface de playground para que eu pudesse experimentar a nova biblioteca em meu navegador. Eu perguntei:

Add a playground.html in the top level folder which loads the necessary ES modules from ./src/... and implements the exact same functionality as seen on https://tools.simonwillison.net/justhtml but using the JavaScript library instead of Pyodide

Ele buscou minha página existente do playground usando curl e construiu um novo playground.html arquivo que carregou o novo código JavaScript. Isso funcionou perfeitamente.

Habilitei o GitHub Pages para meu repositório ainda privado, o que significa que pude acessar o novo playground neste URL:

https://simonw.github.io/justjshtml/playground.html

Tudo o que precisava agora era alguma documentação:

Add a comprehensive README with full usage instructions including attribution plus how this was built plus how to use in in HTML plus how to use it in Node.js

Você pode ler o resultado aqui.

Estamos agora com oito prompts no total, durando pouco mais de quatro horas e eu decorei para o Natal e assisti Wake Up Dead Man no Netflix.

De acordo com o Codex CLI:

Token usage: total=2,089,858 input=1,464,295 (+ 97,122,176 cached) output=625,563 (reasoning 437,010)

Minha calculadora llm-prices.com estima que custaria US$ 29,41 se eu estivesse pagando por esses tokens a preços de API, mas eles foram incluídos em minha assinatura ChatGPT Plus de US$ 20/mês, então o custo extra real para mim foi zero.

Isso levanta tantas questões

  • Esta biblioteca representa uma violação legal de direitos autorais da biblioteca Rust ou da biblioteca Python?
  • Mesmo que isto seja legal, é ético construir uma biblioteca desta forma?
  • Este formato de desenvolvimento prejudica o ecossistema de código aberto?
  • É responsável por publicar bibliotecas de software construídas desta forma?
  • Quão melhor seria esta biblioteca se uma equipe de especialistas a elaborasse manualmente ao longo de vários meses?



Source link

Postagens Similares

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *